1 ///###////////////////////////////////////////////////////////////////////////
2 //
3 // Burton Computer Corporation
4 // http://www.burton-computer.com
5 // http://www.cooldevtools.com
6 // $Id: MailMessageReader.cc 272 2007-01-06 19:37:27Z brian $
7 //
8 // Copyright (C) 2007 Burton Computer Corporation
9 // ALL RIGHTS RESERVED
10 //
11 // This program is open source software; you can redistribute it
12 // and/or modify it under the terms of the Q Public License (QPL)
13 // version 1.0. Use of this software in whole or in part, including
14 // linking it (modified or unmodified) into other programs is
15 // subject to the terms of the QPL.
16 //
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // Q Public License for more details.
21 //
22 // You should have received a copy of the Q Public License
23 // along with this program; see the file LICENSE.txt. If not, visit
24 // the Burton Computer Corporation or CoolDevTools web site
25 // QPL pages at:
26 //
27 // http://www.burton-computer.com/qpl.html
28 // http://www.cooldevtools.com/qpl.html
29 //
30
31 #include <cstdlib>
32 #include "RegularExpression.h"
33 #include "MailMessage.h"
34 #include "MailMessageList.h"
35 #include "LineReader.h"
36 #include "MultiLineString.h"
37 #include "MailMessageReader.h"
38
39 // Defines how many chars to deduct from content-length so that we can
40 // find a blank line before the message delimiter line that follows
41 // the message.
42 static const int CONTENT_LENGTH_PADDING = 10;
43
MailMessageReader(bool use_content_length)44 MailMessageReader::MailMessageReader(bool use_content_length)
45 : m_useContentLength(use_content_length)
46 {
47 }
48
~MailMessageReader()49 MailMessageReader::~MailMessageReader()
50 {
51 }
52
findContentLength(MultiLineString * text,int & content_length)53 bool MailMessageReader::findContentLength(MultiLineString *text,
54 int &content_length)
55 {
56 RegularExpression regex("^content-length: *([0-9]+)", 2, true);
57 for (int i = 0; i < text->lineCount(); ++i) {
58 if (regex.match(text->line(i))) {
59 string buffer;
60 content_length = max(0, atoi(regex.getMatch(1, buffer).c_str()) - CONTENT_LENGTH_PADDING);
61 return true;
62 }
63 }
64 return false;
65 }
66
readMessage()67 OWNED MailMessage *MailMessageReader::readMessage()
68 {
69 Ref<MultiLineString> text(new MultiLineString());
70 if (m_useContentLength) {
71 readMessageWithContentLength(text.ptr());
72 } else {
73 readMessageWithBoundary(text.ptr(), false);
74 }
75 return (text->lineCount() > 0) ? new MailMessage(text) : 0;
76 }
77
readMessageWithBoundary(MultiLineString * text,bool append_to_last_line)78 void MailMessageReader::readMessageWithBoundary(MultiLineString *text,
79 bool append_to_last_line)
80 {
81 while (reader()->hasLine()) {
82 if (isNewMessageBoundary(reader()->currentLine())) {
83 break;
84 }
85 if (is_debug) {
86 cerr << "LINE: '" << reader()->currentLine() << "'" << endl;
87 }
88 if (append_to_last_line) {
89 text->appendToLastLine(reader()->currentLine());
90 append_to_last_line = false;
91 } else {
92 text->addLine(reader()->currentLine());
93 }
94 reader()->forward();
95 }
96 }
97
readMessageWithContentLength(MultiLineString * text)98 void MailMessageReader::readMessageWithContentLength(MultiLineString *text)
99 {
100 while (reader()->hasLine()) {
101 if (is_debug) {
102 cerr << "HDR: '" << reader()->currentLine() << "'" << endl;
103 }
104 text->addLine(reader()->currentLine());
105 if (reader()->currentLine().length() == 0) {
106 break;
107 }
108 reader()->forward();
109 }
110
111 bool should_append = false;
112 int content_length = 0;
113 if (findContentLength(text, content_length)) {
114 should_append = content_length > 0;
115 while (reader()->forward(content_length)) {
116 if (is_debug) {
117 cerr << "CL: " << content_length << ": " << reader()->currentLine() << endl;
118 }
119 text->addLine(reader()->currentLine());
120 }
121 reader()->forward();
122 }
123
124 readMessageWithBoundary(text, should_append);
125 }
126
isNewMessageBoundary(const string & line)127 bool MailMessageReader::isNewMessageBoundary(const string &line)
128 {
129 return false;
130 }
131