summaryrefslogtreecommitdiffstats
path: root/libmail/nntpfetch.C
diff options
context:
space:
mode:
Diffstat (limited to 'libmail/nntpfetch.C')
-rw-r--r--libmail/nntpfetch.C186
1 files changed, 186 insertions, 0 deletions
diff --git a/libmail/nntpfetch.C b/libmail/nntpfetch.C
new file mode 100644
index 0000000..4bd80a9
--- /dev/null
+++ b/libmail/nntpfetch.C
@@ -0,0 +1,186 @@
+/*
+** Copyright 2003, Double Precision Inc.
+**
+** See COPYING for distribution information.
+*/
+#include "nntpfetch.H"
+#include <sstream>
+
+using namespace std;
+
+mail::nntp::FetchTaskBase::FetchTaskBase(mail::callback *callbackArg,
+ nntp &myserverArg,
+ std::string groupNameArg,
+ size_t msgNumArg,
+ std::string uidArg,
+ mail::readMode getTypeArg)
+ : GroupTask(callbackArg, myserverArg, groupNameArg),
+ msgNum(msgNumArg),
+ uid(uidArg),
+ getType(getTypeArg)
+{
+}
+
+mail::nntp::FetchTaskBase::~FetchTaskBase()
+{
+}
+
+void mail::nntp::FetchTaskBase::selectedGroup(msgnum_t estimatedCount,
+ msgnum_t loArticleCount,
+ msgnum_t hiArticleCount)
+{
+ response_func= &mail::nntp::FetchTaskBase::processStatusResponse;
+
+ if (!myserver->fixGenericMessageNumber(uid, msgNum))
+ {
+ fail("Invalid message number.");
+ return;
+ }
+
+ byteCount=0;
+ ostringstream o;
+
+ switch (getType) {
+ case mail::readContents:
+ o << "BODY ";
+ break;
+ case mail::readBoth:
+ o << "ARTICLE ";
+ break;
+ default:
+ o << "HEAD ";
+ }
+
+ o << myserver->index[msgNum].msgNum << "\r\n";
+
+ myserver->socketWrite(o.str());
+}
+
+void mail::nntp::FetchTaskBase::processGroup(const char *cmd)
+{
+ (this->*response_func)(cmd);
+}
+
+void mail::nntp::FetchTaskBase::processStatusResponse(const char *msg)
+{
+ if (msg[0] != '2')
+ {
+ ostringstream o;
+
+ o << "The following error occured while reading this article:\n"
+ "\n"
+ " " << msg << "\n\n";
+
+ fetchedText(o.str());
+ success("Ok");
+ return;
+ }
+
+ response_func= getType == mail::readHeadersFolded
+ ? &mail::nntp::FetchTaskBase::processFetchFoldedResponse:
+ &mail::nntp::FetchTaskBase::processFetchResponse;
+ foldedNewline=false;
+}
+
+void mail::nntp::FetchTaskBase::processFetchResponse(const char *cmd)
+{
+ if (strcmp(cmd, "."))
+ {
+ if (*cmd == '.')
+ ++cmd;
+
+ string s(cmd);
+
+ s += "\n";
+
+ byteCount += s.size();
+ if (callbackPtr)
+ callbackPtr->reportProgress(byteCount, 0, 0, 1);
+ fetchedText(s);
+ return;
+ }
+
+ if (callbackPtr)
+ callbackPtr->reportProgress(byteCount, byteCount, 0, 1);
+ success("Ok\n");
+}
+
+void mail::nntp::FetchTaskBase::processFetchFoldedResponse(const char *cmd)
+{
+ if (strcmp(cmd, "."))
+ {
+ if (*cmd == '.')
+ ++cmd;
+
+ if (*cmd && unicode_isspace((unsigned char)*cmd) &&
+ foldedNewline)
+ {
+ while (*cmd && unicode_isspace((unsigned char)*cmd))
+ cmd++;
+
+ string s(" ");
+ s += cmd;
+
+ byteCount += s.size();
+
+ if (callbackPtr)
+ callbackPtr->
+ reportProgress(byteCount, 0, 0, 1);
+ fetchedText(s);
+ }
+ else
+ {
+ string s;
+
+ if (foldedNewline)
+ s += "\n";
+ foldedNewline=true;
+ s += cmd;
+
+ byteCount += s.size();
+ if (callbackPtr)
+ callbackPtr->
+ reportProgress(byteCount, 0, 0, 1);
+ fetchedText(s);
+ }
+ return;
+ }
+ ++byteCount;
+
+ if (callbackPtr)
+ callbackPtr->reportProgress(byteCount, byteCount, 0, 1);
+
+ fetchedText("\n");
+ success("Ok");
+}
+
+//
+// TaskBase is recyled by CacheTask, which also fetches a message's contents,
+// but does not have a callback::message, because it goes into a temporary
+// file. That's why we separate out callback::message-specific processing
+// into a subclass.
+//
+
+mail::nntp::FetchTask::FetchTask(callback::message *textCallbackArg,
+ nntp &myserverArg,
+ std::string groupNameArg,
+ size_t msgNumArg,
+ std::string uidArg,
+ mail::readMode getType)
+ : FetchTaskBase(textCallbackArg, myserverArg,
+ groupNameArg,
+ msgNumArg,
+ uidArg,
+ getType),
+ textCallback(*textCallbackArg)
+{
+}
+
+mail::nntp::FetchTask::~FetchTask()
+{
+}
+
+void mail::nntp::FetchTask::fetchedText(std::string s)
+{
+ textCallback.messageTextCallback(msgNum, s);
+}