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

OverviewFmt.h

Go to the documentation of this file.
00001 #ifndef __OverviewFmt_h__
00002 #define __OverviewFmt_h__
00003 #include <stdlib.h>
00004 #include <stdio.h>
00005 #include <string.h>
00006 
00007 #include <string>
00008 
00009 #include "config.h"
00010 #include "NSError.h"
00011 #include "Debug.h"
00012 #include "Article.h"
00013 #include "readline.h"
00014 
00028 #define CONF_OverviewFmt {"Subject:","From:","Date:",\
00029        "Message-ID:","References:","Bytes:","Lines:",\
00030        "Xref:full",NULL}
00031 
00036 class OverviewFmt {
00037       private:
00038         struct overdesc {
00039                 char name[256]; // Name of field includeing :
00040                 int len;        // strlen(name)
00041                 int full;       // 1 full header, 0 exclude name of field
00042         };
00043         struct transtab {
00044                 int trans, full;
00045         };
00046         /* xoout ... Output format of overview-database
00047          * xohdrs ... Headers of overview-database --- same as xoout, except
00048          *            the full suffix
00049          * trans[i] ... Position of i-th overview record field (in my format) 
00050          *              in incoming records
00051          * transflg ... Indicates, whether the header has to be prepended
00052          *              or stripped.
00053          * dotrans ... Indicates, whether incoming database records have
00054          *             to be translated
00055          */
00056         overdesc _over[128];
00057         transtab _trans[128];
00058         int _osz;
00059 
00060       public:
00061         int dotrans;
00062          OverviewFmt() {
00063                 const char *tmp[] = CONF_OverviewFmt, *q;
00064                 char *p;
00065                 for (_osz = 0; tmp[_osz]; _osz++) {
00066                         p = _over[_osz].name;
00067                         q = tmp[_osz];
00068                         while ((*p++ = *q++) != ':');
00069                         *p = '\0';
00070                         _over[_osz].len = p - _over[_osz].name;
00071                         _over[_osz].full = (*q == 'f') ? 1 : 0;
00072                 } dotrans = 0;
00073         }
00074 
00084         string getfield(const char *over, const char *fld, int full = -1) {
00085                 string field;
00086                 int i;
00087 
00088                 for (i = 0; i < _osz; i++) {
00089                         if (strcasecmp(fld, _over[i].name) == 0) {
00090                                 int j = i + 1;
00091                                 const char *p = over, *q;
00092 
00093                                 while (*p && j) {
00094                                         if (*p++ == '\t')
00095                                                 j--;
00096                                 }
00097                                 q = p;
00098                                 while (*q && *q != '\t')
00099                                         q++;
00100                                 if (full == -1 || full == _over[i].full) {
00101                                         // No fieldname needs to be added/stripped
00102                                         field.assign(p, q - p);
00103                                         return field;
00104                                 }
00105                                 if (full < _over[i].full) {
00106                                         // Strip fieldname
00107                                         while (*p && *p != ':')
00108                                                 p++;
00109                                         while (*p && isspace(*p))
00110                                                 p++;
00111                                         field.assign(p, q - p);
00112                                         return field;
00113                                 }
00114                                 // Add fieldname
00115                                 field = _over[i].name;
00116                                 field += ' ';
00117                                 field.append(p, q - p);
00118                                 return field;
00119                         }
00120                 }
00121                 throw NoSuchFieldError(fld, ERROR_LOCATION);
00122         }
00123 
00128         void readxoin(std::istream & is);
00129 
00136         void convert(const string & recin, string & recout) const {
00137                 int tabs[256];
00138                 int i, j, k, rinsz;
00139                 if (!dotrans) {
00140                         recout = recin;
00141                         return;
00142                 }
00143 
00144                 i = 0;
00145                 rinsz = 0;
00146                 j = recin.length();
00147                 do {
00148                         if (recin[i] == '\t')
00149                                 tabs[rinsz++] = i;
00150                         i++;
00151                 } while (i < j);
00152                 tabs[rinsz] = i;
00153 
00154                 recout = recin.substr(0, tabs[0]);
00155                 for (i = 0; i < _osz; i++) {
00156                         j = _trans[i].trans;
00157                         if (j >= rinsz) {
00158                                 // FIXME! recin has fewer values than it should have
00159                                 // FIXME! Is this an error?
00160                                 // FIXME! Assuming that the missing ones are empty
00161                                 recout += '\t';
00162                         } else if (j >= 0) {
00163                                 if (_trans[i].full == _over[i].full) {
00164                                         // Leave field as is
00165                                         recout +=
00166                                             recin.substr(tabs[j],
00167                                                          tabs[j + 1] -
00168                                                          tabs[j]);
00169                                 } else if (_trans[i].full > _over[i].full) {
00170                                         // Strip fieldname from field
00171                                         k = tabs[j];
00172                                         while (recin[k] != ':'
00173                                                && k < tabs[j + 1])
00174                                                 k++;
00175                                         if (recin[k] != ':') {
00176                                                 // Cannot find fieldname -- leave it as it is
00177                                                 recout +=
00178                                                     recin.substr(tabs[j],
00179                                                                  tabs[j +
00180                                                                       1] -
00181                                                                  tabs[j]);
00182                                         } else {
00183                                                 while (isspace(recin[k])
00184                                                        && k < tabs[j + 1])
00185                                                         k++;
00186                                                 recout += '\t';
00187                                                 recout +=
00188                                                     recin.substr(k,
00189                                                                  tabs[j +
00190                                                                       1] -
00191                                                                  k);
00192                                         }
00193                                 } else {
00194                                         // Add fieldname to field
00195                                         recout += '\t';
00196                                         recout += _over[i].name;
00197                                         recout += ' ';
00198                                         recout +=
00199                                             recin.substr(tabs[j] + 1,
00200                                                          tabs[j + 1] -
00201                                                          tabs[j] - 1);
00202                                 }
00203                         } else {
00204                                 recout += '\t';
00205                         }
00206                 }
00207         }
00208 
00209         void convert(const Article & article, string & recout) const {
00210                 char buf[256];
00211                 string fld;
00212                 int i;
00213 
00214                  sprintf(buf, "%d", article.getnbr());
00215                  recout = buf;
00216                 for (i = 0; i < _osz; i++) {
00217                         recout += '\t';
00218                         try {
00219                                 recout.append(article.
00220                                               getfield(_over[i].name,
00221                                                        _over[i].full));
00222                         }
00223                         catch(NoSuchFieldError & nf) {
00224                                 // Check, whether field==bytes:
00225                                 if (strcasecmp(_over[i].name, "bytes:") ==
00226                                     0) {
00227                                         sprintf(buf, "%d",
00228                                                 article.length());
00229                                         recout.append(buf);
00230                                 }
00231                                 // Field not found => empty
00232                         }
00233                 }
00234         }
00235 
00236         friend std::ostream & operator <<(std::ostream & os,
00237                                           OverviewFmt & o) {
00238                 int i;
00239                 for (i = 0; i < o._osz; i++) {
00240                         os << o._over[i].name;
00241                         if (o._over[i].full)
00242                                 os << "full\r\n";
00243                         else
00244                                 os << "\r\n";
00245                 }
00246                 return os;
00247         }
00248 
00249 };
00250 
00251 #endif

Generated on Sun Oct 24 21:08:19 2004 for NewsCache by doxygen 1.3.6-20040222