00001 #ifndef __RNewsgroup_h__
00002 #define __RNewsgroup_h__
00003
00004 #include <stdio.h>
00005 #include <sys/stat.h>
00006 #include <sys/types.h>
00007 #include <sys/file.h>
00008 #include <unistd.h>
00009 #include <utime.h>
00010 #include <errno.h>
00011 #include <time.h>
00012 #include <fcntl.h>
00013 #include <stdlib.h>
00014 #include <limits.h>
00015
00016 #include <iostream>
00017 #include <fstream>
00018 #include <map>
00019 #include <string>
00020
00021 #include "config.h"
00022 #include "Debug.h"
00023 #include "OverviewFmt.h"
00024 #include "Newsgroup.h"
00025 #include "NServer.h"
00026
00032 class RNewsgroup:public Newsgroup {
00033 typedef std::map < unsigned int, string >::iterator iterator;
00034
00035 std::map < unsigned int, string > _OverviewDB;
00036 unsigned int _first, _last;
00037
00038
00039 RServer *_RemoteServer;
00040
00041 public:
00042 RNewsgroup():Newsgroup(NULL, NULL) {
00043 } RNewsgroup(RServer * srvr, OverviewFmt * fmt, const char *name)
00044 :Newsgroup(fmt, name), _first(1), _last(0), _RemoteServer(srvr) {
00045 }
00046 ~RNewsgroup() {
00047 }
00048
00049 virtual void getsize(unsigned int *f, unsigned int *l) {
00050 *f = _first;
00051 *l = _last;
00052 }
00053
00054 virtual void setsize(unsigned int f, unsigned int l);
00055
00056 virtual void prefetchGroup(int lockgrp = 1) {
00057 }
00058 virtual void prefetchOverview(void) {
00059 }
00060
00061 virtual unsigned int firstnbr() {
00062 return _first;
00063 }
00064 virtual unsigned int lastnbr() {
00065 return _last;
00066 }
00067 virtual int hasrecord(unsigned int i) {
00068 return (_OverviewDB.find(i) != _OverviewDB.end());
00069 }
00070
00071 virtual Article *getarticle(unsigned int nbr) {
00072 try {
00073 Article *a = new Article;
00074 _RemoteServer->article(_NewsgroupName, nbr, a);
00075 return a;
00076 }
00077 catch(...) {
00078 return NULL;
00079 }
00080 }
00081
00082 virtual void freearticle(Article * artp) {
00083 delete artp;
00084 }
00085 virtual void setarticle(Article * art) {
00086 }
00087 virtual void printarticle(std::ostream & os, unsigned int nbr);
00088
00089 virtual const char *getover(unsigned int nbr) {
00090 iterator over = _OverviewDB.find(nbr);
00091 if (over != _OverviewDB.end())
00092 return over->second.c_str();
00093 else
00094 return NULL;
00095 }
00096
00097 virtual void setover(const string & over) {
00098 unsigned int i = atoi(over.c_str());
00099
00100 if (_first <= i && i <= _last) {
00101 _OverviewDB[i] = over;
00102 }
00103 }
00104
00105 virtual void readoverdb(std::istream & is) {
00106 VERB(slog.
00107 p(Logger::Debug) << "RNewsgroup::readoverdb(&is)\n");
00108 string line1, line2;
00109
00110 for (;;) {
00111 nlreadline(is, line1, 0);
00112 if (line1 == "." || is.eof())
00113 break;
00114 if (_OverviewFormat->dotrans) {
00115
00116 _OverviewFormat->convert(line1, line2);
00117 setover(line2);
00118 } else {
00119 setover(line1);
00120 }
00121 }
00122 }
00123
00124 virtual void printheaderdb(ostream & os,
00125 const char *header,
00126 unsigned int f = 0, unsigned int l =
00127 UINT_MAX) {
00128 char xheader[512], *p;
00129 const char *q;
00130 string fld;
00131
00132 p = xheader;
00133 q = header;
00134 while ((*p++ = *q++));
00135 *(p - 1) = ':';
00136 *p = '\0';
00137
00138 iterator begin = _OverviewDB.lower_bound(f), end =
00139 _OverviewDB.end();
00140
00141 while (begin != end) {
00142 unsigned int i = begin->first;
00143 if (l < i)
00144 break;
00145
00146 try {
00147 fld =
00148 _OverviewFormat->
00149 getfield(_OverviewDB[i].c_str(),
00150 xheader, 0);
00151 os << i << " " << fld << "\r\n";
00152 }
00153 catch(NoSuchFieldError & nsfe) {
00154 os << i << " (none)\r\n";
00155 }
00156 ++begin;
00157 }
00158 }
00159
00160 virtual void printlistgroup(ostream & os) {
00161 iterator begin = _OverviewDB.begin(), end =
00162 _OverviewDB.end();
00163
00164 while (begin != end) {
00165 os << begin->first << "\r\n";
00166 ++begin;
00167 }
00168 }
00169 };
00170 #endif