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];
00040 int len;
00041 int full;
00042 };
00043 struct transtab {
00044 int trans, full;
00045 };
00046
00047
00048
00049
00050
00051
00052
00053
00054
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
00102 field.assign(p, q - p);
00103 return field;
00104 }
00105 if (full < _over[i].full) {
00106
00107 while (*p && *p != ':')
00108 p++;
00109 while (*p && isspace(*p))
00110 p++;
00111 field.assign(p, q - p);
00112 return field;
00113 }
00114
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
00159
00160
00161 recout += '\t';
00162 } else if (j >= 0) {
00163 if (_trans[i].full == _over[i].full) {
00164
00165 recout +=
00166 recin.substr(tabs[j],
00167 tabs[j + 1] -
00168 tabs[j]);
00169 } else if (_trans[i].full > _over[i].full) {
00170
00171 k = tabs[j];
00172 while (recin[k] != ':'
00173 && k < tabs[j + 1])
00174 k++;
00175 if (recin[k] != ':') {
00176
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
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
00225 if (strcasecmp(_over[i].name, "bytes:") ==
00226 0) {
00227 sprintf(buf, "%d",
00228 article.length());
00229 recout.append(buf);
00230 }
00231
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