You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
9507 lines
275 KiB
9507 lines
275 KiB
This file is part of MXE.
|
|
See index.html for further information.
|
|
|
|
Commits from master branch of git://github.com/kisli/vmime
|
|
rebased onto version 0.9.1 tarball files.
|
|
|
|
From 17ff5157ffdc749f60b8285f84e64ac5e06d4283 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Tue, 16 Nov 2010 13:28:05 +0000
|
|
Subject: [PATCH 01/39] Started version 0.9.2.
|
|
|
|
|
|
diff --git a/ChangeLog b/ChangeLog
|
|
index 871d055..8fdcdb0 100644
|
|
--- a/ChangeLog
|
|
+++ b/ChangeLog
|
|
@@ -1,4 +1,12 @@
|
|
|
|
+VERSION 0.9.2svn
|
|
+================
|
|
+
|
|
+2010-11-16 Vincent Richard <vincent@vincent-richard.net>
|
|
+
|
|
+ * Started version 0.9.2.
|
|
+
|
|
+
|
|
VERSION 0.9.1
|
|
=============
|
|
|
|
diff --git a/SConstruct b/SConstruct
|
|
index fb01edf..55f9223 100644
|
|
--- a/SConstruct
|
|
+++ b/SConstruct
|
|
@@ -29,7 +29,7 @@ import string
|
|
# Package version number
|
|
packageVersionMajor = 0
|
|
packageVersionMinor = 9
|
|
-packageVersionMicro = 1
|
|
+packageVersionMicro = 2
|
|
|
|
# API version number (libtool)
|
|
#
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From c12ee2b267b9dcfd092a298dfd9a8eec81ab3a0b Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Tue, 30 Nov 2010 14:57:03 +0000
|
|
Subject: [PATCH 02/39] Initialize and delete object.
|
|
|
|
|
|
diff --git a/vmime/net/imap/IMAPParser.hpp b/vmime/net/imap/IMAPParser.hpp
|
|
index 0f3e9ec..d71c3ca 100644
|
|
--- a/vmime/net/imap/IMAPParser.hpp
|
|
+++ b/vmime/net/imap/IMAPParser.hpp
|
|
@@ -3823,7 +3823,9 @@ public:
|
|
|
|
msg_att_item()
|
|
: m_date_time(NULL), m_number(NULL), m_envelope(NULL),
|
|
- m_uniqueid(NULL), m_nstring(NULL), m_body(NULL), m_flag_list(NULL)
|
|
+ m_uniqueid(NULL), m_nstring(NULL), m_body(NULL), m_flag_list(NULL),
|
|
+ m_section(NULL)
|
|
+
|
|
{
|
|
}
|
|
|
|
@@ -3836,6 +3838,7 @@ public:
|
|
delete (m_nstring);
|
|
delete (m_body);
|
|
delete (m_flag_list);
|
|
+ delete (m_section);
|
|
}
|
|
|
|
void go(IMAPParser& parser, string& line, string::size_type* currentPos)
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From fd277afe87485c9d3377964794b76006c6d36a56 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Wed, 8 Dec 2010 08:52:54 +0000
|
|
Subject: [PATCH 03/39] No extra space between ':' and '<' in MAIL FROM and
|
|
RCPT TO. Wait for server response after QUIT and
|
|
before closing connection.
|
|
|
|
|
|
diff --git a/src/net/smtp/SMTPTransport.cpp b/src/net/smtp/SMTPTransport.cpp
|
|
index 204daae..d9fb7b8 100644
|
|
--- a/src/net/smtp/SMTPTransport.cpp
|
|
+++ b/src/net/smtp/SMTPTransport.cpp
|
|
@@ -516,6 +516,7 @@ void SMTPTransport::internalDisconnect()
|
|
try
|
|
{
|
|
sendRequest("QUIT");
|
|
+ readResponse();
|
|
}
|
|
catch (exception&)
|
|
{
|
|
@@ -565,7 +566,7 @@ void SMTPTransport::send(const mailbox& expeditor, const mailboxList& recipients
|
|
// Emit the "MAIL" command
|
|
ref <SMTPResponse> resp;
|
|
|
|
- sendRequest("MAIL FROM: <" + expeditor.getEmail() + ">");
|
|
+ sendRequest("MAIL FROM:<" + expeditor.getEmail() + ">");
|
|
|
|
if ((resp = readResponse())->getCode() != 250)
|
|
{
|
|
@@ -578,7 +579,7 @@ void SMTPTransport::send(const mailbox& expeditor, const mailboxList& recipients
|
|
{
|
|
const mailbox& mbox = *recipients.getMailboxAt(i);
|
|
|
|
- sendRequest("RCPT TO: <" + mbox.getEmail() + ">");
|
|
+ sendRequest("RCPT TO:<" + mbox.getEmail() + ">");
|
|
|
|
if ((resp = readResponse())->getCode() != 250)
|
|
{
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From d64da50e879c0e480d2e65c43e3b903c3e80101f Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Fri, 10 Dec 2010 16:24:06 +0000
|
|
Subject: [PATCH 04/39] Fixed unit test after bug fix.
|
|
|
|
|
|
diff --git a/tests/net/smtp/SMTPTransportTest.cpp b/tests/net/smtp/SMTPTransportTest.cpp
|
|
index 5015552..6552f9e 100644
|
|
--- a/tests/net/smtp/SMTPTransportTest.cpp
|
|
+++ b/tests/net/smtp/SMTPTransportTest.cpp
|
|
@@ -165,7 +165,7 @@ public:
|
|
}
|
|
else if (cmd == "MAIL")
|
|
{
|
|
- VASSERT_EQ("MAIL", std::string("MAIL FROM: <expeditor@test.vmime.org>"), line);
|
|
+ VASSERT_EQ("MAIL", std::string("MAIL FROM:<expeditor@test.vmime.org>"), line);
|
|
|
|
localSend("250 OK\r\n");
|
|
}
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From 130d0aabda2a9988913ad201390796775dc16a65 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Fri, 10 Dec 2010 16:54:38 +0000
|
|
Subject: [PATCH 05/39] Fixed boundary parsing (thanks to John van der Kamp,
|
|
Zarafa).
|
|
|
|
|
|
diff --git a/src/body.cpp b/src/body.cpp
|
|
index 13dff6b..738d3e7 100644
|
|
--- a/src/body.cpp
|
|
+++ b/src/body.cpp
|
|
@@ -127,10 +127,30 @@ void body::parse(const string& buffer, const string::size_type position,
|
|
const string boundarySep("--" + boundary);
|
|
|
|
string::size_type partStart = position;
|
|
- string::size_type pos = buffer.find(boundarySep, position);
|
|
+ string::size_type pos = position;
|
|
|
|
bool lastPart = false;
|
|
|
|
+ while (pos != string::npos && pos < end)
|
|
+ {
|
|
+ pos = buffer.find(boundarySep, pos);
|
|
+
|
|
+ if (pos == string::npos ||
|
|
+ ((pos == 0 || buffer[pos - 1] == '\n') &&
|
|
+ (buffer[pos + boundarySep.length()] == '\r' ||
|
|
+ buffer[pos + boundarySep.length()] == '\n' ||
|
|
+ buffer[pos + boundarySep.length()] == '-'
|
|
+ )
|
|
+ )
|
|
+ )
|
|
+ {
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ // boundary not a beginning of line, or just a prefix of another, continue the search.
|
|
+ pos++;
|
|
+ }
|
|
+
|
|
if (pos != string::npos && pos < end)
|
|
{
|
|
m_prologText = string(buffer.begin() + position, buffer.begin() + pos);
|
|
@@ -181,7 +201,26 @@ void body::parse(const string& buffer, const string::size_type position,
|
|
}
|
|
|
|
partStart = pos;
|
|
- pos = buffer.find(boundarySep, partStart);
|
|
+
|
|
+ while (pos != string::npos && pos < end)
|
|
+ {
|
|
+ pos = buffer.find(boundarySep, pos);
|
|
+
|
|
+ if (pos == string::npos ||
|
|
+ ((pos == 0 || buffer[pos - 1] == '\n') &&
|
|
+ (buffer[pos + boundarySep.length()] == '\r' ||
|
|
+ buffer[pos + boundarySep.length()] == '\n' ||
|
|
+ buffer[pos + boundarySep.length()] == '-'
|
|
+ )
|
|
+ )
|
|
+ )
|
|
+ {
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ // boundary not a beginning of line, or just a prefix of another, continue the search.
|
|
+ pos++;
|
|
+ }
|
|
}
|
|
|
|
m_contents = vmime::create <emptyContentHandler>();
|
|
diff --git a/tests/parser/bodyPartTest.cpp b/tests/parser/bodyPartTest.cpp
|
|
index 12c4f74..df2bf85 100644
|
|
--- a/tests/parser/bodyPartTest.cpp
|
|
+++ b/tests/parser/bodyPartTest.cpp
|
|
@@ -84,7 +84,7 @@ VMIME_TEST_SUITE_BEGIN
|
|
vmime::string str =
|
|
"Content-Type: multipart/mixed; boundary=\"MY-BOUNDARY\""
|
|
"\r\n\r\n"
|
|
- "--MY-BOUNDARY\r\nHEADER1\r\n\r\nBODY1"
|
|
+ "--MY-BOUNDARY\r\nHEADER1\r\n\r\nBODY1\r\n"
|
|
"--MY-BOUNDARY\r\nHEADER2\r\n\r\nBODY2";
|
|
|
|
vmime::bodyPart p;
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From c63f37c888798f0e7e99aa03afda16445a72b7b2 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Fri, 21 Jan 2011 15:28:06 +0000
|
|
Subject: [PATCH 06/39] Fixed possible infinite loop (thanks to John van der
|
|
Kamp, Zarafa).
|
|
|
|
|
|
diff --git a/src/word.cpp b/src/word.cpp
|
|
index db720dc..1c1c1a6 100644
|
|
--- a/src/word.cpp
|
|
+++ b/src/word.cpp
|
|
@@ -386,7 +386,7 @@ void word::generate(utility::outputStream& os, const string::size_type maxLineLe
|
|
|
|
maxRunLength = std::max(maxRunLength, curRunLength);
|
|
|
|
- if (maxRunLength >= maxLineLength - 3)
|
|
+ if (((flags & text::FORCE_NO_ENCODING) == 0) && maxRunLength >= maxLineLength - 3)
|
|
{
|
|
// Generate with encoding forced
|
|
generate(os, maxLineLength, curLinePos, newLinePos, flags | text::FORCE_ENCODING, state);
|
|
diff --git a/tests/parser/textTest.cpp b/tests/parser/textTest.cpp
|
|
index b84f376..746ac94 100644
|
|
--- a/tests/parser/textTest.cpp
|
|
+++ b/tests/parser/textTest.cpp
|
|
@@ -52,6 +52,7 @@ VMIME_TEST_SUITE_BEGIN
|
|
VMIME_TEST(testWhitespaceMBox)
|
|
|
|
VMIME_TEST(testFoldingAscii)
|
|
+ VMIME_TEST(testForcedNonEncoding)
|
|
VMIME_TEST_LIST_END
|
|
|
|
|
|
@@ -442,5 +443,15 @@ VMIME_TEST_SUITE_BEGIN
|
|
" =?us-ascii?Q?9012345678901234567890123456789?=", w.generate(50));
|
|
}
|
|
|
|
+ void testForcedNonEncoding()
|
|
+ {
|
|
+ // Testing long unbreakable and unencodable header
|
|
+ vmime::relay r;
|
|
+ r.parse(" from User (Ee9GMqZQ8t7IQwftfAFHd2KyScCYRrFSJ50tKEoXv2bVCG4HcPU80GGWiFabAvG77FekpGgF1h@[127.0.0.1]) by servername.hostname.com\n\t"
|
|
+ "with esmtp id 1NGTS9-2C0sqG0; Fri, 4 Dec 2009 09:23:49 +0100");
|
|
+
|
|
+ VASSERT_EQ("received.long", "from User\r\n (Ee9GMqZQ8t7IQwftfAFHd2KyScCYRrFSJ50tKEoXv2bVCG4HcPU80GGWiFabAvG77FekpGgF1h@[127.0.0.1])\r\n by servername.hostname.com with esmtp id 1NGTS9-2C0sqG0; Fri, 4 Dec 2009\r\n 09:23:49 +0100", r.generate(78));
|
|
+ }
|
|
+
|
|
VMIME_TEST_SUITE_END
|
|
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From 1fafad8f913e700b350e6915de8be710fc2d1ced Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Fri, 28 Jan 2011 12:11:08 +0000
|
|
Subject: [PATCH 07/39] Fixed possible read to invalid memory location (thanks
|
|
to Alexander Konovalov).
|
|
|
|
|
|
diff --git a/src/word.cpp b/src/word.cpp
|
|
index 1c1c1a6..fa08d33 100644
|
|
--- a/src/word.cpp
|
|
+++ b/src/word.cpp
|
|
@@ -460,7 +460,7 @@ void word::generate(utility::outputStream& os, const string::size_type maxLineLe
|
|
|
|
os << string(curLineStart, p);
|
|
|
|
- if (parserHelpers::isSpace(*(p - 1)))
|
|
+ if (p != m_buffer.begin() && parserHelpers::isSpace(*(p - 1)))
|
|
state->lastCharIsSpace = true;
|
|
else
|
|
state->lastCharIsSpace = false;
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From 73298423f695d7c4441d44619e4b7f9de75f566e Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Wed, 9 Mar 2011 18:03:31 +0000
|
|
Subject: [PATCH 08/39] Fixed bug #3174903. Fixed word parsing when buffer
|
|
does not end with NL. Fixed 'no encoding' when
|
|
forced.
|
|
|
|
|
|
diff --git a/src/body.cpp b/src/body.cpp
|
|
index 738d3e7..8596833 100644
|
|
--- a/src/body.cpp
|
|
+++ b/src/body.cpp
|
|
@@ -153,7 +153,10 @@ void body::parse(const string& buffer, const string::size_type position,
|
|
|
|
if (pos != string::npos && pos < end)
|
|
{
|
|
- m_prologText = string(buffer.begin() + position, buffer.begin() + pos);
|
|
+ vmime::text text;
|
|
+ text.parse(buffer, position, pos);
|
|
+
|
|
+ m_prologText = text.getWholeBuffer();
|
|
}
|
|
|
|
for (int index = 0 ; !lastPart && (pos != string::npos) && (pos < end) ; ++index)
|
|
@@ -246,7 +249,10 @@ void body::parse(const string& buffer, const string::size_type position,
|
|
// Treat remaining text as epilog
|
|
else if (partStart < end)
|
|
{
|
|
- m_epilogText = string(buffer.begin() + partStart, buffer.begin() + end);
|
|
+ vmime::text text;
|
|
+ text.parse(buffer, partStart, end);
|
|
+
|
|
+ m_epilogText = text.getWholeBuffer();
|
|
}
|
|
}
|
|
// Treat the contents as 'simple' data
|
|
@@ -333,7 +339,7 @@ void body::generate(utility::outputStream& os, const string::size_type maxLineLe
|
|
|
|
if (!prologText.empty())
|
|
{
|
|
- text prolog(word(prologText, getCharset()));
|
|
+ text prolog(prologText, vmime::charset("us-ascii"));
|
|
|
|
prolog.encodeAndFold(os, maxLineLength, 0,
|
|
NULL, text::FORCE_NO_ENCODING | text::NO_NEW_LINE_SEQUENCE);
|
|
@@ -356,7 +362,7 @@ void body::generate(utility::outputStream& os, const string::size_type maxLineLe
|
|
|
|
if (!epilogText.empty())
|
|
{
|
|
- text epilog(word(epilogText, getCharset()));
|
|
+ text epilog(epilogText, vmime::charset("us-ascii"));
|
|
|
|
epilog.encodeAndFold(os, maxLineLength, 0,
|
|
NULL, text::FORCE_NO_ENCODING | text::NO_NEW_LINE_SEQUENCE);
|
|
diff --git a/src/word.cpp b/src/word.cpp
|
|
index fa08d33..aeaa737 100644
|
|
--- a/src/word.cpp
|
|
+++ b/src/word.cpp
|
|
@@ -102,7 +102,9 @@ ref <word> word::parseNext(const string& buffer, const string::size_type positio
|
|
++pos;
|
|
|
|
unencoded += buffer.substr(startPos, endPos - startPos);
|
|
- unencoded += ' ';
|
|
+
|
|
+ if (pos != end) // ignore white-spaces at end
|
|
+ unencoded += ' ';
|
|
|
|
startPos = pos;
|
|
continue;
|
|
@@ -191,14 +193,15 @@ ref <word> word::parseNext(const string& buffer, const string::size_type positio
|
|
++pos;
|
|
}
|
|
|
|
- // Treat unencoded text at the end of the buffer
|
|
- if (end != startPos)
|
|
- {
|
|
- if (startPos != pos && !isFirst && prevIsEncoded)
|
|
- unencoded += whiteSpaces;
|
|
+ if (startPos != end && !isFirst && prevIsEncoded)
|
|
+ unencoded += whiteSpaces;
|
|
|
|
+ if (startPos != end)
|
|
unencoded += buffer.substr(startPos, end - startPos);
|
|
|
|
+ // Treat unencoded text at the end of the buffer
|
|
+ if (!unencoded.empty())
|
|
+ {
|
|
ref <word> w = vmime::create <word>(unencoded, charset(charsets::US_ASCII));
|
|
w->setParsedBounds(position, end);
|
|
|
|
@@ -337,12 +340,14 @@ void word::generate(utility::outputStream& os, const string::size_type maxLineLe
|
|
state = &defaultGeneratorState;
|
|
|
|
// Find out if encoding is forced or required by contents + charset
|
|
- bool encodingNeeded = (flags & text::FORCE_ENCODING) != 0;
|
|
+ bool encodingNeeded = false;
|
|
|
|
- if (encodingNeeded == false)
|
|
- encodingNeeded = wordEncoder::isEncodingNeeded(m_buffer, m_charset);
|
|
- else if ((flags & text::FORCE_NO_ENCODING) != 0)
|
|
+ if ((flags & text::FORCE_NO_ENCODING) != 0)
|
|
encodingNeeded = false;
|
|
+ else if ((flags & text::FORCE_ENCODING) != 0)
|
|
+ encodingNeeded = true;
|
|
+ else // auto-detect
|
|
+ encodingNeeded = wordEncoder::isEncodingNeeded(m_buffer, m_charset);
|
|
|
|
// If possible and requested (with flag), quote the buffer (no folding is performed).
|
|
// Quoting is possible if and only if:
|
|
diff --git a/tests/parser/bodyPartTest.cpp b/tests/parser/bodyPartTest.cpp
|
|
index df2bf85..b129913 100644
|
|
--- a/tests/parser/bodyPartTest.cpp
|
|
+++ b/tests/parser/bodyPartTest.cpp
|
|
@@ -34,6 +34,8 @@ VMIME_TEST_SUITE_BEGIN
|
|
VMIME_TEST(testParse)
|
|
VMIME_TEST(testGenerate)
|
|
VMIME_TEST(testParseMissingLastBoundary)
|
|
+ VMIME_TEST(testPrologEpilog)
|
|
+ VMIME_TEST(testPrologEncoding)
|
|
VMIME_TEST_LIST_END
|
|
|
|
|
|
@@ -105,5 +107,79 @@ VMIME_TEST_SUITE_BEGIN
|
|
VASSERT_EQ("1", "Foo: bar\r\n\r\nBaz", p1.generate());
|
|
}
|
|
|
|
+ void testPrologEpilog()
|
|
+ {
|
|
+ const char testMail[] =
|
|
+ "To: test@vmime.org\r\n"
|
|
+ "From: test@vmime.org\r\n"
|
|
+ "Subject: Prolog and epilog test\r\n"
|
|
+ "Content-Type: multipart/mixed; \r\n"
|
|
+ " boundary=\"=_boundary\"\r\n"
|
|
+ "\r\n"
|
|
+ "Prolog text\r\n"
|
|
+ "--=_boundary\r\n"
|
|
+ "Content-Type: text/plain\r\n"
|
|
+ "\r\n"
|
|
+ "Part1\r\n"
|
|
+ "--=_boundary--\r\n"
|
|
+ "Epilog text";
|
|
+
|
|
+ vmime::bodyPart part;
|
|
+ part.parse(testMail);
|
|
+
|
|
+ VASSERT_EQ("prolog", "Prolog text", part.getBody()->getPrologText());
|
|
+ VASSERT_EQ("epilog", "Epilog text", part.getBody()->getEpilogText());
|
|
+ }
|
|
+
|
|
+ // Test for bug fix: prolog should not be encoded
|
|
+ // http://sourceforge.net/tracker/?func=detail&atid=525568&aid=3174903&group_id=69724
|
|
+ void testPrologEncoding()
|
|
+ {
|
|
+ const char testmail[] =
|
|
+ "To: test@vmime.org\r\n"
|
|
+ "From: test@vmime.org\r\n"
|
|
+ "Subject: Prolog encoding test\r\n"
|
|
+ "Content-Type: multipart/mixed; \r\n"
|
|
+ " boundary=\"=_+ZWjySayKqSf2CyrfnNpaAcO6-G1HpoXdHZ4YyswAWqEY39Q\"\r\n"
|
|
+ "\r\n"
|
|
+ "This is a multi-part message in MIME format. Your mail reader does not\r\n"
|
|
+ "understand MIME message format.\r\n"
|
|
+ "--=_+ZWjySayKqSf2CyrfnNpaAcO6-G1HpoXdHZ4YyswAWqEY39Q\r\n"
|
|
+ "Content-Type: text/html; charset=windows-1251\r\n"
|
|
+ "Content-Transfer-Encoding: quoted-printable\r\n"
|
|
+ "\r\n"
|
|
+ "=DD=F2=EE =F2=E5=EA=F1=F2=EE=E2=E0=FF =F7=E0=F1=F2=FC =F1=EB=EE=E6=ED=EE=E3=\r\n"
|
|
+ "=EE =F1=EE=EE=E1=F9=E5=ED=E8=FF\r\n"
|
|
+ "--=_+ZWjySayKqSf2CyrfnNpaAcO6-G1HpoXdHZ4YyswAWqEY39Q\r\n"
|
|
+ "Content-Type: application/octet-stream; charset=windows-1251\r\n"
|
|
+ "Content-Disposition: attachment; filename=FNS.zip\r\n"
|
|
+ "Content-Transfer-Encoding: base64\r\n"
|
|
+ "\r\n"
|
|
+ "UEsDBB...snap...EEAAAAAA==\r\n"
|
|
+ "--=_+ZWjySayKqSf2CyrfnNpaAcO6-G1HpoXdHZ4YyswAWqEY39Q--\r\n"
|
|
+ "Epilog text";
|
|
+
|
|
+ vmime::ref<vmime::message> msg = vmime::create<vmime::message>();
|
|
+
|
|
+ std::string istr(testmail);
|
|
+
|
|
+ std::string ostr;
|
|
+ vmime::utility::outputStreamStringAdapter out(ostr);
|
|
+
|
|
+ for (int i = 0 ; i < 10 ; ++i)
|
|
+ {
|
|
+ ostr.clear();
|
|
+
|
|
+ msg->parse(istr);
|
|
+ msg->generate(out);
|
|
+
|
|
+ istr = ostr;
|
|
+ }
|
|
+
|
|
+ VASSERT_EQ("prolog", "This is a multi-part message in MIME format. Your mail reader"
|
|
+ " does not understand MIME message format.", msg->getBody()->getPrologText());
|
|
+ VASSERT_EQ("epilog", "Epilog text", msg->getBody()->getEpilogText());
|
|
+ }
|
|
+
|
|
VMIME_TEST_SUITE_END
|
|
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From 5f5757b9d4bb0febb1e2183578eb91e801a08038 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Sun, 27 Mar 2011 11:26:55 +0000
|
|
Subject: [PATCH 09/39] Allow static linking in mingw-cross-env. Added 'iconv'
|
|
and uses 'ws2_32' instead of 'winsock32' (#3213487).
|
|
|
|
|
|
diff --git a/SConstruct b/SConstruct
|
|
index 55f9223..177f5b4 100644
|
|
--- a/SConstruct
|
|
+++ b/SConstruct
|
|
@@ -1089,7 +1089,7 @@ def generateAutotools(target, source, env):
|
|
vmime_pc_in.write("Description: " + packageDescription + "\n")
|
|
vmime_pc_in.write("Version: @VERSION@\n")
|
|
vmime_pc_in.write("Requires: @GSASL_REQUIRED@\n")
|
|
- vmime_pc_in.write("Libs: -L${libdir} -l@GENERIC_VERSIONED_LIBRARY_NAME@ @GSASL_LIBS@ @LIBGNUTLS_LIBS@ @VMIME_ADDITIONAL_PC_LIBS@\n")
|
|
+ vmime_pc_in.write("Libs: -L${libdir} -l@GENERIC_VERSIONED_LIBRARY_NAME@ @GSASL_LIBS@ @LIBGNUTLS_LIBS@ @LIBICONV@ @PTHREAD_LIBS@ @VMIME_ADDITIONAL_PC_LIBS@\n")
|
|
#vmime_pc_in.write("Cflags: -I${includedir}/@GENERIC_VERSIONED_LIBRARY_NAME@\n")
|
|
vmime_pc_in.write("Cflags: -I${includedir}/ @LIBGNUTLS_CFLAGS@\n")
|
|
vmime_pc_in.close()
|
|
@@ -1709,7 +1709,7 @@ fi
|
|
|
|
# -- Link with Winsock (Windows)
|
|
if test "x$VMIME_DETECT_PLATFORM" = "xwindows"; then
|
|
- VMIME_ADDITIONAL_PC_LIBS="$VMIME_ADDITIONAL_PC_LIBS -lwsock32"
|
|
+ VMIME_ADDITIONAL_PC_LIBS="$VMIME_ADDITIONAL_PC_LIBS -lws2_32"
|
|
fi
|
|
|
|
# -- getaddrinfo (POSIX)
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From 2b48b4a68ce3e9b9b1a3f485123af5938a568324 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Thu, 31 Mar 2011 19:13:03 +0000
|
|
Subject: [PATCH 10/39] Flush stateful data from iconv (thanks to John van der
|
|
Kamp, Zarafa).
|
|
|
|
|
|
diff --git a/src/charsetConverter.cpp b/src/charsetConverter.cpp
|
|
index 38b9e5e..2135788 100644
|
|
--- a/src/charsetConverter.cpp
|
|
+++ b/src/charsetConverter.cpp
|
|
@@ -119,6 +119,7 @@ void charsetConverter::convert(utility::inputStream& in, utility::outputStream&
|
|
size_t inPos = 0;
|
|
|
|
bool prevIsInvalid = false;
|
|
+ bool breakAfterNext = false;
|
|
|
|
while (true)
|
|
{
|
|
@@ -126,11 +127,12 @@ void charsetConverter::convert(utility::inputStream& in, utility::outputStream&
|
|
size_t inLength = static_cast <size_t>(in.read(inBuffer + inPos, sizeof(inBuffer) - inPos) + inPos);
|
|
size_t outLength = sizeof(outBuffer);
|
|
|
|
- const char* inPtr = inBuffer;
|
|
+ const char* inPtr = breakAfterNext ? NULL : inBuffer;
|
|
+ size_t *ptrLength = breakAfterNext ? NULL : &inLength;
|
|
char* outPtr = outBuffer;
|
|
|
|
// Convert input bytes
|
|
- if (iconv(cd, ICONV_HACK(&inPtr), &inLength,
|
|
+ if (iconv(cd, ICONV_HACK(&inPtr), ptrLength,
|
|
&outPtr, &outLength) == static_cast <size_t>(-1))
|
|
{
|
|
// Illegal input sequence or input sequence has no equivalent
|
|
@@ -170,9 +172,12 @@ void charsetConverter::convert(utility::inputStream& in, utility::outputStream&
|
|
prevIsInvalid = false;
|
|
}
|
|
|
|
- // Check for end of data
|
|
- if (in.eof() && inPos == 0)
|
|
+ if (breakAfterNext)
|
|
break;
|
|
+
|
|
+ // Check for end of data, loop again to flush stateful data from iconv
|
|
+ if (in.eof() && inPos == 0)
|
|
+ breakAfterNext = true;
|
|
}
|
|
}
|
|
|
|
diff --git a/tests/parser/charsetTest.cpp b/tests/parser/charsetTest.cpp
|
|
index 8ad71d7..54a09a7 100644
|
|
--- a/tests/parser/charsetTest.cpp
|
|
+++ b/tests/parser/charsetTest.cpp
|
|
@@ -100,6 +100,7 @@ VMIME_TEST_SUITE_BEGIN
|
|
VMIME_TEST(testFilterValid1)
|
|
VMIME_TEST(testFilterValid2)
|
|
VMIME_TEST(testFilterValid3)
|
|
+ VMIME_TEST(testEncodingHebrew1255)
|
|
|
|
// Test invalid input
|
|
VMIME_TEST(testFilterInvalid1)
|
|
@@ -227,6 +228,15 @@ VMIME_TEST_SUITE_BEGIN
|
|
VASSERT_EQ("1", toHex(expectedOut), toHex(actualOut));
|
|
}
|
|
|
|
+ void testEncodingHebrew1255()
|
|
+ {
|
|
+ // hewbrew string in windows-1255 charset
|
|
+ const char data[] = "\xe9\xf9\xf7\xf8\xe9\xf9\xf8\xf7\xe9\xe9\xf9";
|
|
+ vmime::word w = vmime::word(data, "windows-1255");
|
|
+ vmime::string encoded = w.generate();
|
|
+ // less than 60% ascii, base64 received
|
|
+ VASSERT_EQ("1", "=?windows-1255?B?6fn3+On5+Pfp6fk=?=", encoded);
|
|
+ }
|
|
|
|
// Conversion to hexadecimal for easier debugging
|
|
static const vmime::string toHex(const vmime::string str)
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From 8d2e039c5201e144ff08e2ff7cf9efe77fe4b3d0 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Fri, 10 Jun 2011 19:39:09 +0000
|
|
Subject: [PATCH 11/39] Requested email change.
|
|
|
|
|
|
diff --git a/AUTHORS b/AUTHORS
|
|
index 20a0181..bbddb30 100644
|
|
--- a/AUTHORS
|
|
+++ b/AUTHORS
|
|
@@ -21,7 +21,7 @@ AUTHORS file.
|
|
- Rafael Fernandez <prf@adinet.com.uy>
|
|
- Xin Li <lixin3@staff.sina.com.cn>
|
|
- Benjamin Biron <benbiron@gmail.com>
|
|
- - Bertrand Benoit <bsquare@bsquare.levillage.org>
|
|
+ - Bertrand Benoit <projettwk@users.sourceforge.net>
|
|
- Tim Teulings <rael@edge.ping.de>
|
|
- Georg Sauthoff <gsauthof@techfak.uni-bielefeld.de>
|
|
- Pierre Thierry <nowhere.man@levallois.eu.org> (patches for STL algorithms)
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From cc6317f28ae0b61fea36e1bc78b09dc8300579f8 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Tue, 14 Jun 2011 18:37:54 +0000
|
|
Subject: [PATCH 12/39] Fixed compilation issue following namespace change.
|
|
|
|
|
|
diff --git a/examples/example7.cpp b/examples/example7.cpp
|
|
index 1ddb3d0..243b1da 100644
|
|
--- a/examples/example7.cpp
|
|
+++ b/examples/example7.cpp
|
|
@@ -43,18 +43,18 @@ int main()
|
|
vmime::platform::setHandler<vmime::platforms::posix::posixHandler>();
|
|
|
|
// Enumerate encoders
|
|
- vmime::encoderFactory* ef = vmime::encoderFactory::getInstance();
|
|
+ vmime::utility::encoder::encoderFactory* ef = vmime::utility::encoder::encoderFactory::getInstance();
|
|
|
|
std::cout << "Available encoders:" << std::endl;
|
|
|
|
for (int i = 0 ; i < ef->getEncoderCount() ; ++i)
|
|
{
|
|
- vmime::ref <const vmime::encoderFactory::registeredEncoder>
|
|
+ vmime::ref <const vmime::utility::encoder::encoderFactory::registeredEncoder>
|
|
enc = ef->getEncoderAt(i);
|
|
|
|
std::cout << " * " << enc->getName() << std::endl;
|
|
|
|
- vmime::ref <vmime::encoder> e = enc->create();
|
|
+ vmime::ref <vmime::utility::encoder::encoder> e = enc->create();
|
|
|
|
std::vector <vmime::string> props = e->getAvailableProperties();
|
|
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From a916d12d44ac43fc8e4729e0a91f4d6243f29a11 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Sun, 19 Jun 2011 17:51:33 +0000
|
|
Subject: [PATCH 13/39] Fixed parsing of an attachment filename that is
|
|
between 66 and 76 characters long (Zarafa).
|
|
|
|
|
|
diff --git a/src/parameter.cpp b/src/parameter.cpp
|
|
index 91a7e5c..f59d5ab 100644
|
|
--- a/src/parameter.cpp
|
|
+++ b/src/parameter.cpp
|
|
@@ -281,7 +281,8 @@ void parameter::generate(utility::outputStream& os, const string::size_type maxL
|
|
bool needQuoting = false;
|
|
string::size_type valueLength = 0;
|
|
|
|
- for (string::size_type i = 0 ; (i < value.length()) && (pos + valueLength < maxLineLength - 4) ; ++i, ++valueLength)
|
|
+ // Use worst-case length name.length()+2 for 'name=' part of line
|
|
+ for (string::size_type i = 0 ; (i < value.length()) && (pos + name.length() + 2 + valueLength < maxLineLength - 4) ; ++i, ++valueLength)
|
|
{
|
|
switch (value[i])
|
|
{
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From 9735165c57000a6368e91ce8852206a20930c1ca Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Sun, 19 Jun 2011 18:08:12 +0000
|
|
Subject: [PATCH 14/39] Correctly generate attachment names which are long and
|
|
have high characters for Outlook Express (Zarafa).
|
|
|
|
|
|
diff --git a/src/parameter.cpp b/src/parameter.cpp
|
|
index f59d5ab..d757e1b 100644
|
|
--- a/src/parameter.cpp
|
|
+++ b/src/parameter.cpp
|
|
@@ -268,17 +268,19 @@ void parameter::generate(utility::outputStream& os, const string::size_type maxL
|
|
// value is to be generated.
|
|
|
|
// A stream for a temporary storage
|
|
- std::ostringstream sevenBitBuffer;
|
|
+ std::string sevenBitBuffer;
|
|
+ utility::outputStreamStringAdapter sevenBitStream(sevenBitBuffer);
|
|
|
|
string::size_type pos = curLinePos;
|
|
|
|
if (pos + name.length() + 10 + value.length() > maxLineLength)
|
|
{
|
|
- sevenBitBuffer << NEW_LINE_SEQUENCE;
|
|
+ sevenBitStream << NEW_LINE_SEQUENCE;
|
|
pos = NEW_LINE_SEQUENCE_LENGTH;
|
|
}
|
|
|
|
bool needQuoting = false;
|
|
+ bool needQuotedPrintable = false;
|
|
string::size_type valueLength = 0;
|
|
|
|
// Use worst-case length name.length()+2 for 'name=' part of line
|
|
@@ -308,6 +310,16 @@ void parameter::generate(utility::outputStream& os, const string::size_type maxL
|
|
|
|
needQuoting = true;
|
|
break;
|
|
+
|
|
+ default:
|
|
+
|
|
+ if (!parserHelpers::isAscii(value[i]))
|
|
+ {
|
|
+ needQuotedPrintable = true;
|
|
+ needQuoting = true;
|
|
+ }
|
|
+
|
|
+ break;
|
|
}
|
|
}
|
|
|
|
@@ -315,12 +327,12 @@ void parameter::generate(utility::outputStream& os, const string::size_type maxL
|
|
|
|
if (needQuoting)
|
|
{
|
|
- sevenBitBuffer << name << "=\"";
|
|
+ sevenBitStream << name << "=\"";
|
|
pos += name.length() + 2;
|
|
}
|
|
else
|
|
{
|
|
- sevenBitBuffer << name << "=";
|
|
+ sevenBitStream << name << "=";
|
|
pos += name.length() + 1;
|
|
}
|
|
|
|
@@ -332,29 +344,43 @@ void parameter::generate(utility::outputStream& os, const string::size_type maxL
|
|
const bool alwaysEncode = m_value.getCharset().getRecommendedEncoding(recommendedEnc);
|
|
bool extended = alwaysEncode;
|
|
|
|
- for (string::size_type i = 0 ; (i < value.length()) && (pos < maxLineLength - 4) ; ++i)
|
|
+ if (needQuotedPrintable)
|
|
{
|
|
- const char_t c = value[i];
|
|
-
|
|
- if (/* needQuoting && */ (c == '"' || c == '\\')) // 'needQuoting' is implicit
|
|
- {
|
|
- sevenBitBuffer << '\\' << value[i]; // escape 'x' with '\x'
|
|
- pos += 2;
|
|
- }
|
|
- else if (parserHelpers::isAscii(c))
|
|
- {
|
|
- sevenBitBuffer << value[i];
|
|
- ++pos;
|
|
- }
|
|
- else
|
|
+ // Send the name in quoted-printable, so outlook express et.al.
|
|
+ // will understand the real filename
|
|
+ size_t oldLen = sevenBitBuffer.length();
|
|
+ m_value.generate(sevenBitStream);
|
|
+ pos += sevenBitBuffer.length() - oldLen;
|
|
+ extended = true; // also send with RFC-2231 encoding
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ // Do not chop off this value, but just add the complete name as one header line.
|
|
+ for (string::size_type i = 0 ; i < value.length() ; ++i)
|
|
{
|
|
- extended = true;
|
|
+ const char_t c = value[i];
|
|
+
|
|
+ if (/* needQuoting && */ (c == '"' || c == '\\')) // 'needQuoting' is implicit
|
|
+ {
|
|
+ sevenBitStream << '\\' << value[i]; // escape 'x' with '\x'
|
|
+ pos += 2;
|
|
+ }
|
|
+ else if (parserHelpers::isAscii(c))
|
|
+ {
|
|
+ sevenBitStream << value[i];
|
|
+ ++pos;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ extended = true;
|
|
+ }
|
|
}
|
|
- }
|
|
+
|
|
+ } // !needQuotedPrintable
|
|
|
|
if (needQuoting)
|
|
{
|
|
- sevenBitBuffer << '"';
|
|
+ sevenBitStream << '"';
|
|
++pos;
|
|
}
|
|
|
|
@@ -532,7 +558,7 @@ void parameter::generate(utility::outputStream& os, const string::size_type maxL
|
|
// "7bit/us-ascii" will suffice in this case.
|
|
|
|
// Output what has been stored in temporary buffer so far
|
|
- os << sevenBitBuffer.str();
|
|
+ os << sevenBitBuffer;
|
|
}
|
|
#endif // !VMIME_ALWAYS_GENERATE_7BIT_PARAMETER
|
|
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From 8d69ad6849d8d6b211674942157f2af8bcd51c26 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Sun, 19 Jun 2011 18:16:49 +0000
|
|
Subject: [PATCH 15/39] Alias for UTF-7 charset.
|
|
|
|
|
|
diff --git a/src/charset.cpp b/src/charset.cpp
|
|
index e043186..0fda450 100644
|
|
--- a/src/charset.cpp
|
|
+++ b/src/charset.cpp
|
|
@@ -45,6 +45,9 @@ charset::charset()
|
|
charset::charset(const string& name)
|
|
: m_name(name)
|
|
{
|
|
+ // If we receive this rfc-1642 valid MIME charset, convert it to something usefull for iconv
|
|
+ if (utility::stringUtils::isStringEqualNoCase(m_name, "unicode-1-1-utf-7"))
|
|
+ m_name = "utf-7";
|
|
}
|
|
|
|
|
|
@@ -60,6 +63,10 @@ void charset::parse(const string& buffer, const string::size_type position,
|
|
m_name = utility::stringUtils::trim
|
|
(string(buffer.begin() + position, buffer.begin() + end));
|
|
|
|
+ // If we parsed this rfc-1642 valid MIME charset, convert it to something usefull for iconv
|
|
+ if (utility::stringUtils::isStringEqualNoCase(m_name, "unicode-1-1-utf-7"))
|
|
+ m_name = "utf-7";
|
|
+
|
|
setParsedBounds(position, end);
|
|
|
|
if (newPosition)
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From ccd95daf9cdd7171fc2027afa5d0ad80b0475ded Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Sun, 19 Jun 2011 18:39:35 +0000
|
|
Subject: [PATCH 16/39] Fixed messageBuilder to accept an empty mailbox group
|
|
in 'To:' field, to allow for undisclosed-recipients
|
|
(Zarafa).
|
|
|
|
|
|
diff --git a/src/messageBuilder.cpp b/src/messageBuilder.cpp
|
|
index 870d59e..3597b3a 100644
|
|
--- a/src/messageBuilder.cpp
|
|
+++ b/src/messageBuilder.cpp
|
|
@@ -51,17 +51,15 @@ ref <message> messageBuilder::construct() const
|
|
// Generate the header fields
|
|
msg->getHeader()->Subject()->setValue(m_subject);
|
|
|
|
- if (m_from.isEmpty())
|
|
- throw exceptions::no_expeditor();
|
|
-
|
|
- if ((m_to.isEmpty() || m_to.getAddressAt(0)->isEmpty()) &&
|
|
+ if (((m_to.isEmpty()) || (m_to.getAddressAt(0)->isEmpty() && !m_to.getAddressAt(0)->isGroup())) &&
|
|
(m_cc.isEmpty() || m_cc.getAddressAt(0)->isEmpty()) &&
|
|
(m_bcc.isEmpty() || m_bcc.getAddressAt(0)->isEmpty()))
|
|
{
|
|
throw exceptions::no_recipient();
|
|
}
|
|
|
|
- msg->getHeader()->From()->setValue(m_from);
|
|
+ if (!m_from.isEmpty())
|
|
+ msg->getHeader()->From()->setValue(m_from);
|
|
|
|
if (!m_to.isEmpty())
|
|
msg->getHeader()->To()->setValue(m_to);
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From 583e25bcdee132e53e0792cd8f0d8e535cabb743 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Sun, 19 Jun 2011 18:49:55 +0000
|
|
Subject: [PATCH 17/39] Added support for mailboxes that specify an (encoded)
|
|
full name with an empty email address, set by a <>
|
|
marker (Zarafa).
|
|
|
|
|
|
diff --git a/src/mailbox.cpp b/src/mailbox.cpp
|
|
index 5cb0139..fea7479 100644
|
|
--- a/src/mailbox.cpp
|
|
+++ b/src/mailbox.cpp
|
|
@@ -88,6 +88,7 @@ void mailbox::parse(const string& buffer, const string::size_type position,
|
|
// Temporary buffers for extracted name and address
|
|
string name;
|
|
string address;
|
|
+ bool hadBrackets = false;
|
|
|
|
while (p < pend)
|
|
{
|
|
@@ -283,6 +284,7 @@ void mailbox::parse(const string& buffer, const string::size_type position,
|
|
}
|
|
else if (*p == '>')
|
|
{
|
|
+ hadBrackets = true;
|
|
break;
|
|
}
|
|
else if (!parserHelpers::isSpace(*p))
|
|
@@ -309,7 +311,7 @@ void mailbox::parse(const string& buffer, const string::size_type position,
|
|
|
|
// Swap name and address when no address was found
|
|
// (email address is mandatory, whereas name is optional).
|
|
- if (address.empty() && !name.empty())
|
|
+ if (address.empty() && !name.empty() && !hadBrackets)
|
|
{
|
|
m_email.clear();
|
|
m_email.reserve(name.size());
|
|
diff --git a/tests/parser/mailboxTest.cpp b/tests/parser/mailboxTest.cpp
|
|
index 8411daa..9ebadca 100644
|
|
--- a/tests/parser/mailboxTest.cpp
|
|
+++ b/tests/parser/mailboxTest.cpp
|
|
@@ -32,6 +32,7 @@ VMIME_TEST_SUITE_BEGIN
|
|
|
|
VMIME_TEST_LIST_BEGIN
|
|
VMIME_TEST(testParse)
|
|
+ VMIME_TEST(testEmptyEmailAddress)
|
|
VMIME_TEST_LIST_END
|
|
|
|
|
|
@@ -113,5 +114,19 @@ VMIME_TEST_SUITE_BEGIN
|
|
}
|
|
}
|
|
|
|
+ void testEmptyEmailAddress()
|
|
+ {
|
|
+ vmime::addressList addrList;
|
|
+ addrList.parse("\"Full Name\" <>");
|
|
+
|
|
+ VASSERT_EQ("count", 1, addrList.getAddressCount());
|
|
+ VASSERT_EQ("!group", false, addrList.getAddressAt(0)->isGroup());
|
|
+
|
|
+ vmime::ref <vmime::mailbox> mbox = addrList.getAddressAt(0).dynamicCast <vmime::mailbox>();
|
|
+
|
|
+ VASSERT_EQ("name", "Full Name", mbox->getName());
|
|
+ VASSERT_EQ("email", "", mbox->getEmail());
|
|
+ }
|
|
+
|
|
VMIME_TEST_SUITE_END
|
|
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From 461b92f84d5c16b297d33610fcd89fc7ca5a161a Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Fri, 24 Jun 2011 15:46:23 +0000
|
|
Subject: [PATCH 18/39] Added missing libs in pkg-config file.
|
|
|
|
|
|
diff --git a/SConstruct b/SConstruct
|
|
index 177f5b4..37c0ac6 100644
|
|
--- a/SConstruct
|
|
+++ b/SConstruct
|
|
@@ -1089,7 +1089,7 @@ def generateAutotools(target, source, env):
|
|
vmime_pc_in.write("Description: " + packageDescription + "\n")
|
|
vmime_pc_in.write("Version: @VERSION@\n")
|
|
vmime_pc_in.write("Requires: @GSASL_REQUIRED@\n")
|
|
- vmime_pc_in.write("Libs: -L${libdir} -l@GENERIC_VERSIONED_LIBRARY_NAME@ @GSASL_LIBS@ @LIBGNUTLS_LIBS@ @LIBICONV@ @PTHREAD_LIBS@ @VMIME_ADDITIONAL_PC_LIBS@\n")
|
|
+ vmime_pc_in.write("Libs: -L${libdir} -l@GENERIC_VERSIONED_LIBRARY_NAME@ @GSASL_LIBS@ @LIBGNUTLS_LIBS@ @LIBICONV@ @PTHREAD_LIBS@ @LIBICONV@ @PTHREAD_LIBS@ @VMIME_ADDITIONAL_PC_LIBS@\n")
|
|
#vmime_pc_in.write("Cflags: -I${includedir}/@GENERIC_VERSIONED_LIBRARY_NAME@\n")
|
|
vmime_pc_in.write("Cflags: -I${includedir}/ @LIBGNUTLS_CFLAGS@\n")
|
|
vmime_pc_in.close()
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From 2b2c0abd02a17ccff7d49e266b9854f4ea47f8e4 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Sat, 25 Jun 2011 17:07:53 +0000
|
|
Subject: [PATCH 19/39] Fixed parsing of empty body parts (thanks to John van
|
|
der Kamp, from Zarafa).
|
|
|
|
|
|
diff --git a/src/body.cpp b/src/body.cpp
|
|
index 8596833..9d7d57f 100644
|
|
--- a/src/body.cpp
|
|
+++ b/src/body.cpp
|
|
@@ -197,6 +197,11 @@ void body::parse(const string& buffer, const string::size_type position,
|
|
{
|
|
ref <bodyPart> part = vmime::create <bodyPart>();
|
|
|
|
+ // End before start may happen on empty bodyparts (directly
|
|
+ // successive boundaries without even a line-break)
|
|
+ if (partEnd < partStart)
|
|
+ std::swap(partStart, partEnd);
|
|
+
|
|
part->parse(buffer, partStart, partEnd, NULL);
|
|
part->m_parent = m_part;
|
|
|
|
diff --git a/tests/parser/bodyPartTest.cpp b/tests/parser/bodyPartTest.cpp
|
|
index b129913..075b8f9 100644
|
|
--- a/tests/parser/bodyPartTest.cpp
|
|
+++ b/tests/parser/bodyPartTest.cpp
|
|
@@ -36,6 +36,7 @@ VMIME_TEST_SUITE_BEGIN
|
|
VMIME_TEST(testParseMissingLastBoundary)
|
|
VMIME_TEST(testPrologEpilog)
|
|
VMIME_TEST(testPrologEncoding)
|
|
+ VMIME_TEST(testSuccessiveBoundaries)
|
|
VMIME_TEST_LIST_END
|
|
|
|
|
|
@@ -181,5 +182,23 @@ VMIME_TEST_SUITE_BEGIN
|
|
VASSERT_EQ("epilog", "Epilog text", msg->getBody()->getEpilogText());
|
|
}
|
|
|
|
+ void testSuccessiveBoundaries()
|
|
+ {
|
|
+ vmime::string str =
|
|
+ "Content-Type: multipart/mixed; boundary=\"MY-BOUNDARY\""
|
|
+ "\r\n\r\n"
|
|
+ "--MY-BOUNDARY\r\nHEADER1\r\n\r\nBODY1\r\n"
|
|
+ "--MY-BOUNDARY\r\n"
|
|
+ "--MY-BOUNDARY--\r\n";
|
|
+
|
|
+ vmime::bodyPart p;
|
|
+ p.parse(str);
|
|
+
|
|
+ VASSERT_EQ("count", 2, p.getBody()->getPartCount());
|
|
+
|
|
+ VASSERT_EQ("part1-body", "BODY1", extractContents(p.getBody()->getPartAt(0)->getBody()->getContents()));
|
|
+ VASSERT_EQ("part2-body", "", extractContents(p.getBody()->getPartAt(1)->getBody()->getContents()));
|
|
+ }
|
|
+
|
|
VMIME_TEST_SUITE_END
|
|
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From 2648d744da0e2e744c7959999ac513c3016072b4 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Sun, 26 Jun 2011 08:19:11 +0000
|
|
Subject: [PATCH 20/39] Use gnutls_priority_set_direct() instead of GNUTLS
|
|
deprecated functions.
|
|
|
|
|
|
diff --git a/SConstruct b/SConstruct
|
|
index 37c0ac6..01ad3f3 100644
|
|
--- a/SConstruct
|
|
+++ b/SConstruct
|
|
@@ -816,6 +816,7 @@ else:
|
|
config_hpp.write('// -- TLS/SSL support\n')
|
|
if env['with_tls'] == 'yes':
|
|
config_hpp.write('#define VMIME_HAVE_TLS_SUPPORT 1\n')
|
|
+ config_hpp.write('#define HAVE_GNUTLS_PRIORITY_FUNCS 1\n')
|
|
else:
|
|
config_hpp.write('#define VMIME_HAVE_TLS_SUPPORT 0\n')
|
|
|
|
@@ -1626,11 +1627,42 @@ if test "x$conf_tls" = "xyes"; then
|
|
else
|
|
AC_MSG_ERROR(can't find an usable version of GNU TLS library)
|
|
fi
|
|
+
|
|
+ # -- check for gnutls_priority_set_direct() function
|
|
+ if test "x$have_gnutls" = "xyes"; then
|
|
+ AC_MSG_CHECKING(for gnutls_priority_set_direct)
|
|
+
|
|
+ LIBS_save="$LIBS"
|
|
+ LIBS="$LIBS $LIBGNUTLS_LIBS"
|
|
+ CPPFLAGS_save="$CPPFLAGS"
|
|
+ CPPFLAGS="$CPPFLAGS $LIBGNUTLS_CFLAGS"
|
|
+
|
|
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <gnutls/gnutls.h>],
|
|
+ [gnutls_session s; gnutls_priority_set_direct(s, NULL, NULL);])],
|
|
+ [have_gnutls_priority_funcs=yes],
|
|
+ [have_gnutls_priority_funcs=no])
|
|
+
|
|
+ CPPFLAGS="$CPPFLAGS_save"
|
|
+ LIBS="$LIBS_save"
|
|
+
|
|
+ AC_MSG_RESULT([$have_gnutls_priority_funcs])
|
|
+
|
|
+ if test "x$have_gnutls_priority_funcs" = "xyes"; then
|
|
+ AM_CONDITIONAL(HAVE_GNUTLS_PRIORITY_FUNCS, true)
|
|
+ HAVE_GNUTLS_PRIORITY_FUNCS=1
|
|
+ else
|
|
+ AM_CONDITIONAL(HAVE_GNUTLS_PRIORITY_FUNCS, false)
|
|
+ HAVE_GNUTLS_PRIORITY_FUNCS=0
|
|
+ fi
|
|
+ fi
|
|
else
|
|
AM_CONDITIONAL(VMIME_HAVE_TLS_SUPPORT, false)
|
|
VMIME_HAVE_TLS_SUPPORT=0
|
|
fi
|
|
|
|
+AC_SUBST(LIBGNUTLS_CFLAGS)
|
|
+AC_SUBST(LIBGNUTLS_LIBS)
|
|
+
|
|
# ** platform handlers
|
|
|
|
VMIME_BUILTIN_PLATFORMS=''
|
|
@@ -1919,6 +1951,7 @@ typedef unsigned ${VMIME_TYPE_INT32} vmime_uint32;
|
|
#define VMIME_HAVE_SASL_SUPPORT ${VMIME_HAVE_SASL_SUPPORT}
|
|
// -- TLS support
|
|
#define VMIME_HAVE_TLS_SUPPORT ${VMIME_HAVE_TLS_SUPPORT}
|
|
+#define HAVE_GNUTLS_PRIORITY_FUNCS ${HAVE_GNUTLS_PRIORITY_FUNCS}
|
|
// -- Messaging support
|
|
#define VMIME_HAVE_MESSAGING_FEATURES ${VMIME_HAVE_MESSAGING_FEATURES}
|
|
""")
|
|
diff --git a/src/net/tls/TLSSession.cpp b/src/net/tls/TLSSession.cpp
|
|
index 010c007..af73a05 100644
|
|
--- a/src/net/tls/TLSSession.cpp
|
|
+++ b/src/net/tls/TLSSession.cpp
|
|
@@ -123,6 +123,21 @@ TLSSession::TLSSession(ref <security::cert::certificateVerifier> cv)
|
|
|
|
// Sets some default priority on the ciphers, key exchange methods,
|
|
// macs and compression methods.
|
|
+#if HAVE_GNUTLS_PRIORITY_FUNCS
|
|
+
|
|
+ if ((res = gnutls_priority_set_direct
|
|
+ (*m_gnutlsSession, "NORMAL:%SSL3_RECORD_VERSION", NULL)) != 0)
|
|
+ {
|
|
+ if ((res = gnutls_priority_set_direct
|
|
+ (*m_gnutlsSession, "NORMAL", NULL)) != 0)
|
|
+ {
|
|
+ throwTLSException
|
|
+ ("gnutls_priority_set_direct", res);
|
|
+ }
|
|
+ }
|
|
+
|
|
+#else // !HAVE_GNUTLS_PRIORITY_FUNCS
|
|
+
|
|
gnutls_set_default_priority(*m_gnutlsSession);
|
|
|
|
// Sets the priority on the certificate types supported by gnutls.
|
|
@@ -197,6 +212,8 @@ TLSSession::TLSSession(ref <security::cert::certificateVerifier> cv)
|
|
|
|
gnutls_compression_set_priority(*m_gnutlsSession, compressionPriority);
|
|
|
|
+#endif // !HAVE_GNUTLS_PRIORITY_FUNCS
|
|
+
|
|
// Initialize credentials
|
|
gnutls_credentials_set(*m_gnutlsSession,
|
|
GNUTLS_CRD_ANON, g_gnutlsGlobal.anonCred);
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From 1060121ffd4315c3158ffc001040f4f705514e7a Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Sun, 26 Jun 2011 12:47:25 +0000
|
|
Subject: [PATCH 21/39] Fixed encoding of whitespace. Fixed old test case.
|
|
|
|
|
|
diff --git a/src/text.cpp b/src/text.cpp
|
|
index 2454456..66c3b35 100644
|
|
--- a/src/text.cpp
|
|
+++ b/src/text.cpp
|
|
@@ -320,12 +320,6 @@ void text::createFromString(const string& in, const charset& ch)
|
|
}
|
|
else
|
|
{
|
|
- if (count)
|
|
- {
|
|
- ref <word> w = getWordAt(getWordCount() - 1);
|
|
- w->getBuffer() += ' ';
|
|
- }
|
|
-
|
|
appendWord(vmime::create <word>
|
|
(chunk, charset(charsets::US_ASCII)));
|
|
|
|
diff --git a/tests/parser/textTest.cpp b/tests/parser/textTest.cpp
|
|
index 746ac94..43ec836 100644
|
|
--- a/tests/parser/textTest.cpp
|
|
+++ b/tests/parser/textTest.cpp
|
|
@@ -53,6 +53,8 @@ VMIME_TEST_SUITE_BEGIN
|
|
|
|
VMIME_TEST(testFoldingAscii)
|
|
VMIME_TEST(testForcedNonEncoding)
|
|
+
|
|
+ VMIME_TEST(testBugFix20110511)
|
|
VMIME_TEST_LIST_END
|
|
|
|
|
|
@@ -149,7 +151,7 @@ VMIME_TEST_SUITE_BEGIN
|
|
VASSERT_EQ("2.1", 3, t2.getWordCount());
|
|
VASSERT_EQ("2.2", "some ASCII characters and special chars: ", t2.getWordAt(0)->getBuffer());
|
|
VASSERT_EQ("2.3", vmime::charset(vmime::charsets::US_ASCII), t2.getWordAt(0)->getCharset());
|
|
- VASSERT_EQ("2.4", "\xf1\xf2\xf3\xf4 ", t2.getWordAt(1)->getBuffer());
|
|
+ VASSERT_EQ("2.4", "\xf1\xf2\xf3\xf4", t2.getWordAt(1)->getBuffer());
|
|
VASSERT_EQ("2.5", c2, t2.getWordAt(1)->getCharset());
|
|
VASSERT_EQ("2.6", "and then more ASCII chars.", t2.getWordAt(2)->getBuffer());
|
|
VASSERT_EQ("2.7", vmime::charset(vmime::charsets::US_ASCII), t2.getWordAt(2)->getCharset());
|
|
@@ -453,5 +455,43 @@ VMIME_TEST_SUITE_BEGIN
|
|
VASSERT_EQ("received.long", "from User\r\n (Ee9GMqZQ8t7IQwftfAFHd2KyScCYRrFSJ50tKEoXv2bVCG4HcPU80GGWiFabAvG77FekpGgF1h@[127.0.0.1])\r\n by servername.hostname.com with esmtp id 1NGTS9-2C0sqG0; Fri, 4 Dec 2009\r\n 09:23:49 +0100", r.generate(78));
|
|
}
|
|
|
|
+ void testBugFix20110511()
|
|
+ {
|
|
+ /*
|
|
+
|
|
+ Using the latest version of vmime (0.9.1), encoding the following string: Jean
|
|
+ Gwenaël Dutourd will result in:
|
|
+ Jean =?utf-8?Q?Gwena=C3=ABl_?= Dutourd
|
|
+ However, decoding this will result in Jean Gwenaël Dutourd (notice two spaces
|
|
+ between the last 2 words). The encoder adds a _ after the second word, but
|
|
+ since the last word is not encoded, the space between them is not ignored, and
|
|
+ is decoded into an additional space.
|
|
+
|
|
+ See: http://sourceforge.net/projects/vmime/forums/forum/237357/topic/4531365
|
|
+
|
|
+ */
|
|
+
|
|
+ const std::string DECODED_TEXT = "Jean Gwenaël Dutourd";
|
|
+ const std::string ENCODED_TEXT = "Jean =?utf-8?Q?Gwena=C3=ABl?= Dutourd";
|
|
+
|
|
+ // Encode
|
|
+ VASSERT_EQ("encode", ENCODED_TEXT,
|
|
+ vmime::text::newFromString(DECODED_TEXT, vmime::charset("utf-8"))->generate());
|
|
+
|
|
+ // Decode
|
|
+ vmime::text t;
|
|
+ t.parse(ENCODED_TEXT);
|
|
+
|
|
+ // -- words
|
|
+ std::ostringstream oss; oss << t;
|
|
+ VASSERT_EQ("decode1",
|
|
+ "[text: [[word: charset=us-ascii, buffer=Jean ],"
|
|
+ "[word: charset=utf-8, buffer=Gwenaël],"
|
|
+ "[word: charset=us-ascii, buffer= Dutourd]]]", oss.str());
|
|
+
|
|
+ // -- getWholeBuffer
|
|
+ VASSERT_EQ("decode2", DECODED_TEXT, t.getWholeBuffer());
|
|
+ }
|
|
+
|
|
VMIME_TEST_SUITE_END
|
|
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From dc6dc039fc0edccf4630894fa6ed8cd4bf3bb3ce Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Sat, 20 Aug 2011 06:35:06 +0000
|
|
Subject: [PATCH 22/39] Use gnutls_strerror() for reporting errors.
|
|
|
|
|
|
diff --git a/src/net/tls/TLSSession.cpp b/src/net/tls/TLSSession.cpp
|
|
index af73a05..7426a73 100644
|
|
--- a/src/net/tls/TLSSession.cpp
|
|
+++ b/src/net/tls/TLSSession.cpp
|
|
@@ -41,6 +41,9 @@
|
|
//#define GNUTLS_DEBUG 1
|
|
|
|
|
|
+#include <sstream>
|
|
+#include <iomanip>
|
|
+
|
|
#if VMIME_DEBUG && GNUTLS_DEBUG
|
|
#include <iostream>
|
|
#endif // VMIME_DEBUG && GNUTLS_DEBUG
|
|
@@ -257,119 +260,14 @@ ref <security::cert::certificateVerifier> TLSSession::getCertificateVerifier()
|
|
|
|
void TLSSession::throwTLSException(const string& fname, const int code)
|
|
{
|
|
- string msg = fname + "() returned ";
|
|
-
|
|
-#define ERROR(x) \
|
|
- case x: msg += #x; break;
|
|
-
|
|
- switch (code)
|
|
- {
|
|
- ERROR(GNUTLS_E_SUCCESS)
|
|
- ERROR(GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM)
|
|
- ERROR(GNUTLS_E_UNKNOWN_CIPHER_TYPE)
|
|
- ERROR(GNUTLS_E_LARGE_PACKET)
|
|
- ERROR(GNUTLS_E_UNSUPPORTED_VERSION_PACKET)
|
|
- ERROR(GNUTLS_E_UNEXPECTED_PACKET_LENGTH)
|
|
- ERROR(GNUTLS_E_INVALID_SESSION)
|
|
- ERROR(GNUTLS_E_FATAL_ALERT_RECEIVED)
|
|
- ERROR(GNUTLS_E_UNEXPECTED_PACKET)
|
|
- ERROR(GNUTLS_E_WARNING_ALERT_RECEIVED)
|
|
- ERROR(GNUTLS_E_ERROR_IN_FINISHED_PACKET)
|
|
- ERROR(GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET)
|
|
- ERROR(GNUTLS_E_UNKNOWN_CIPHER_SUITE)
|
|
- ERROR(GNUTLS_E_UNWANTED_ALGORITHM)
|
|
- ERROR(GNUTLS_E_MPI_SCAN_FAILED)
|
|
- ERROR(GNUTLS_E_DECRYPTION_FAILED)
|
|
- ERROR(GNUTLS_E_MEMORY_ERROR)
|
|
- ERROR(GNUTLS_E_DECOMPRESSION_FAILED)
|
|
- ERROR(GNUTLS_E_COMPRESSION_FAILED)
|
|
- ERROR(GNUTLS_E_AGAIN)
|
|
- ERROR(GNUTLS_E_EXPIRED)
|
|
- ERROR(GNUTLS_E_DB_ERROR)
|
|
- ERROR(GNUTLS_E_SRP_PWD_ERROR)
|
|
- ERROR(GNUTLS_E_INSUFFICIENT_CREDENTIALS)
|
|
- ERROR(GNUTLS_E_HASH_FAILED)
|
|
- ERROR(GNUTLS_E_BASE64_DECODING_ERROR)
|
|
- ERROR(GNUTLS_E_MPI_PRINT_FAILED)
|
|
- ERROR(GNUTLS_E_REHANDSHAKE)
|
|
- ERROR(GNUTLS_E_GOT_APPLICATION_DATA)
|
|
- ERROR(GNUTLS_E_RECORD_LIMIT_REACHED)
|
|
- ERROR(GNUTLS_E_ENCRYPTION_FAILED)
|
|
- ERROR(GNUTLS_E_PK_ENCRYPTION_FAILED)
|
|
- ERROR(GNUTLS_E_PK_DECRYPTION_FAILED)
|
|
- ERROR(GNUTLS_E_PK_SIGN_FAILED)
|
|
- ERROR(GNUTLS_E_X509_UNSUPPORTED_CRITICAL_EXTENSION)
|
|
- ERROR(GNUTLS_E_KEY_USAGE_VIOLATION)
|
|
- ERROR(GNUTLS_E_NO_CERTIFICATE_FOUND)
|
|
- ERROR(GNUTLS_E_INVALID_REQUEST)
|
|
- ERROR(GNUTLS_E_SHORT_MEMORY_BUFFER)
|
|
- ERROR(GNUTLS_E_INTERRUPTED)
|
|
- ERROR(GNUTLS_E_PUSH_ERROR)
|
|
- ERROR(GNUTLS_E_PULL_ERROR)
|
|
- ERROR(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER)
|
|
- ERROR(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
|
|
- ERROR(GNUTLS_E_PKCS1_WRONG_PAD)
|
|
- ERROR(GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION)
|
|
- ERROR(GNUTLS_E_INTERNAL_ERROR)
|
|
- ERROR(GNUTLS_E_DH_PRIME_UNACCEPTABLE)
|
|
- ERROR(GNUTLS_E_FILE_ERROR)
|
|
- ERROR(GNUTLS_E_TOO_MANY_EMPTY_PACKETS)
|
|
- ERROR(GNUTLS_E_UNKNOWN_PK_ALGORITHM)
|
|
- ERROR(GNUTLS_E_INIT_LIBEXTRA)
|
|
- ERROR(GNUTLS_E_LIBRARY_VERSION_MISMATCH)
|
|
- ERROR(GNUTLS_E_NO_TEMPORARY_RSA_PARAMS)
|
|
- ERROR(GNUTLS_E_LZO_INIT_FAILED)
|
|
- ERROR(GNUTLS_E_NO_COMPRESSION_ALGORITHMS)
|
|
- ERROR(GNUTLS_E_NO_CIPHER_SUITES)
|
|
- ERROR(GNUTLS_E_OPENPGP_GETKEY_FAILED)
|
|
- ERROR(GNUTLS_E_PK_SIG_VERIFY_FAILED)
|
|
- ERROR(GNUTLS_E_ILLEGAL_SRP_USERNAME)
|
|
- ERROR(GNUTLS_E_SRP_PWD_PARSING_ERROR)
|
|
- ERROR(GNUTLS_E_NO_TEMPORARY_DH_PARAMS)
|
|
- ERROR(GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
|
|
- ERROR(GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND)
|
|
- ERROR(GNUTLS_E_ASN1_DER_ERROR)
|
|
- ERROR(GNUTLS_E_ASN1_VALUE_NOT_FOUND)
|
|
- ERROR(GNUTLS_E_ASN1_GENERIC_ERROR)
|
|
- ERROR(GNUTLS_E_ASN1_VALUE_NOT_VALID)
|
|
- ERROR(GNUTLS_E_ASN1_TAG_ERROR)
|
|
- ERROR(GNUTLS_E_ASN1_TAG_IMPLICIT)
|
|
- ERROR(GNUTLS_E_ASN1_TYPE_ANY_ERROR)
|
|
- ERROR(GNUTLS_E_ASN1_SYNTAX_ERROR)
|
|
- ERROR(GNUTLS_E_ASN1_DER_OVERFLOW)
|
|
- //ERROR(GNUTLS_E_OPENPGP_TRUSTDB_VERSION_UNSUPPORTED)
|
|
- ERROR(GNUTLS_E_OPENPGP_UID_REVOKED)
|
|
- ERROR(GNUTLS_E_CERTIFICATE_ERROR)
|
|
- //ERROR(GNUTLS_E_X509_CERTIFICATE_ERROR)
|
|
- ERROR(GNUTLS_E_CERTIFICATE_KEY_MISMATCH)
|
|
- ERROR(GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE)
|
|
- ERROR(GNUTLS_E_X509_UNKNOWN_SAN)
|
|
- ERROR(GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED)
|
|
- ERROR(GNUTLS_E_X509_UNSUPPORTED_ATTRIBUTE)
|
|
- ERROR(GNUTLS_E_UNKNOWN_HASH_ALGORITHM)
|
|
- ERROR(GNUTLS_E_UNKNOWN_PKCS_CONTENT_TYPE)
|
|
- ERROR(GNUTLS_E_UNKNOWN_PKCS_BAG_TYPE)
|
|
- ERROR(GNUTLS_E_INVALID_PASSWORD)
|
|
- ERROR(GNUTLS_E_MAC_VERIFY_FAILED)
|
|
- ERROR(GNUTLS_E_CONSTRAINT_ERROR)
|
|
- ERROR(GNUTLS_E_BASE64_ENCODING_ERROR)
|
|
- ERROR(GNUTLS_E_INCOMPATIBLE_GCRYPT_LIBRARY)
|
|
- //ERROR(GNUTLS_E_INCOMPATIBLE_CRYPTO_LIBRARY)
|
|
- ERROR(GNUTLS_E_INCOMPATIBLE_LIBTASN1_LIBRARY)
|
|
- ERROR(GNUTLS_E_OPENPGP_KEYRING_ERROR)
|
|
- ERROR(GNUTLS_E_X509_UNSUPPORTED_OID)
|
|
- //ERROR(GNUTLS_E_RANDOM_FAILED)
|
|
- ERROR(GNUTLS_E_UNIMPLEMENTED_FEATURE)
|
|
-
|
|
- default:
|
|
-
|
|
- msg += "unknown error";
|
|
- break;
|
|
- }
|
|
+ std::ostringstream msg;
|
|
|
|
-#undef ERROR
|
|
+ msg << fname + "() returned code ";
|
|
+ msg << std::hex << code;
|
|
+ msg << ": ";
|
|
+ msg << gnutls_strerror(code);
|
|
|
|
- throw exceptions::tls_exception(msg);
|
|
+ throw exceptions::tls_exception(msg.str());
|
|
}
|
|
|
|
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From 7ea6fc3737ef36407e1c90f3aa05f89a39bdefb7 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Sun, 21 Aug 2011 08:55:46 +0000
|
|
Subject: [PATCH 23/39] Removed dependency on gcrypt for gnutls version >=
|
|
2.12.
|
|
|
|
|
|
diff --git a/src/net/tls/TLSSession.cpp b/src/net/tls/TLSSession.cpp
|
|
index 7426a73..d3f6d49 100644
|
|
--- a/src/net/tls/TLSSession.cpp
|
|
+++ b/src/net/tls/TLSSession.cpp
|
|
@@ -26,9 +26,17 @@
|
|
|
|
#include "vmime/config.hpp"
|
|
|
|
+// Dependency on gcrypt is not needed since GNU TLS version 2.12.
|
|
+// See here: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=638651
|
|
+#if GNUTLS_VERSION_NUMBER <= 0x020b00
|
|
+# define VMIME_GNUTLS_NEEDS_GCRYPT 1
|
|
+#endif
|
|
+
|
|
#if VMIME_HAVE_PTHREAD
|
|
# include <pthread.h>
|
|
-# include <gcrypt.h>
|
|
+# if VMIME_GNUTLS_NEEDS_GCRYPT
|
|
+# include <gcrypt.h>
|
|
+# endif
|
|
# include <errno.h>
|
|
#endif // VMIME_HAVE_PTHREAD
|
|
|
|
@@ -49,7 +57,7 @@
|
|
#endif // VMIME_DEBUG && GNUTLS_DEBUG
|
|
|
|
|
|
-#if VMIME_HAVE_PTHREAD && defined(GCRY_THREAD_OPTION_PTHREAD_IMPL)
|
|
+#if VMIME_HAVE_PTHREAD && VMIME_GNUTLS_NEEDS_GCRYPT && defined(GCRY_THREAD_OPTION_PTHREAD_IMPL)
|
|
extern "C"
|
|
{
|
|
GCRY_THREAD_OPTION_PTHREAD_IMPL;
|
|
@@ -70,7 +78,9 @@ struct TLSGlobal
|
|
TLSGlobal()
|
|
{
|
|
#if VMIME_HAVE_PTHREAD && defined(GCRY_THREAD_OPTION_PTHREAD_IMPL)
|
|
+ #if VMIME_GNUTLS_NEEDS_GCRYPT
|
|
gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
|
|
+ #endif // VMIME_GNUTLS_NEEDS_GCRYPT
|
|
#endif // VMIME_HAVE_PTHREAD && defined(GCRY_THREAD_OPTION_PTHREAD_IMPL
|
|
|
|
gnutls_global_init();
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From f21c55be642b166a2f0518ace2b179bed3916b23 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Sun, 21 Aug 2011 09:04:46 +0000
|
|
Subject: [PATCH 24/39] Fixed HAVE_GNUTLS_PRIORITY_FUNCS never defined when
|
|
configured with no TLS support.
|
|
|
|
|
|
diff --git a/SConstruct b/SConstruct
|
|
index 01ad3f3..11e884b 100644
|
|
--- a/SConstruct
|
|
+++ b/SConstruct
|
|
@@ -1654,10 +1654,16 @@ if test "x$conf_tls" = "xyes"; then
|
|
AM_CONDITIONAL(HAVE_GNUTLS_PRIORITY_FUNCS, false)
|
|
HAVE_GNUTLS_PRIORITY_FUNCS=0
|
|
fi
|
|
+ else
|
|
+ AM_CONDITIONAL(HAVE_GNUTLS_PRIORITY_FUNCS, false)
|
|
+ HAVE_GNUTLS_PRIORITY_FUNCS=0
|
|
fi
|
|
else
|
|
AM_CONDITIONAL(VMIME_HAVE_TLS_SUPPORT, false)
|
|
VMIME_HAVE_TLS_SUPPORT=0
|
|
+
|
|
+ AM_CONDITIONAL(HAVE_GNUTLS_PRIORITY_FUNCS, false)
|
|
+ HAVE_GNUTLS_PRIORITY_FUNCS=0
|
|
fi
|
|
|
|
AC_SUBST(LIBGNUTLS_CFLAGS)
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From d4e66226a696745adafa1767210580f8fbb7ae00 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Tue, 15 Nov 2011 11:40:42 +0000
|
|
Subject: [PATCH 25/39] GNU TLS 3 has no 'extra' (thanks to mabrand).
|
|
|
|
|
|
diff --git a/src/net/tls/TLSSession.cpp b/src/net/tls/TLSSession.cpp
|
|
index d3f6d49..cb50acc 100644
|
|
--- a/src/net/tls/TLSSession.cpp
|
|
+++ b/src/net/tls/TLSSession.cpp
|
|
@@ -22,7 +22,9 @@
|
|
//
|
|
|
|
#include <gnutls/gnutls.h>
|
|
+#if GNUTLS_VERSION_NUMBER < 0x030000
|
|
#include <gnutls/extra.h>
|
|
+#endif
|
|
|
|
#include "vmime/config.hpp"
|
|
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From bacbe512e406d22f6acc83597fcdfc2d624cf82b Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Tue, 15 Nov 2011 11:46:07 +0000
|
|
Subject: [PATCH 26/39] Set Diffie-Hellman prime size (bug SF#3434852).
|
|
|
|
|
|
diff --git a/src/net/tls/TLSSession.cpp b/src/net/tls/TLSSession.cpp
|
|
index cb50acc..0606808 100644
|
|
--- a/src/net/tls/TLSSession.cpp
|
|
+++ b/src/net/tls/TLSSession.cpp
|
|
@@ -139,6 +139,7 @@ TLSSession::TLSSession(ref <security::cert::certificateVerifier> cv)
|
|
// Sets some default priority on the ciphers, key exchange methods,
|
|
// macs and compression methods.
|
|
#if HAVE_GNUTLS_PRIORITY_FUNCS
|
|
+ gnutls_dh_set_prime_bits(*m_gnutlsSession, 128);
|
|
|
|
if ((res = gnutls_priority_set_direct
|
|
(*m_gnutlsSession, "NORMAL:%SSL3_RECORD_VERSION", NULL)) != 0)
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From 6574b60a303c5d864e840aa23959656bb2803485 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Thu, 22 Dec 2011 08:51:28 +0000
|
|
Subject: [PATCH 27/39] Updated coding conventions.
|
|
|
|
|
|
diff --git a/HACKING b/HACKING
|
|
index 4f35a53..f51d738 100644
|
|
--- a/HACKING
|
|
+++ b/HACKING
|
|
@@ -1,10 +1,10 @@
|
|
|
|
-This file contains coding guidelines for VMime. You should follow these
|
|
-guidelines if you want to contribute to VMime. It guarantees some minimal
|
|
-quality of the code.
|
|
+This file contains coding guidelines for VMime. You should follow them
|
|
+if you want to contribute to VMime. The rules below are not guidelines
|
|
+or recommendations, but strict rules.
|
|
|
|
|
|
-1. General guidelines
|
|
+1. General rules
|
|
1.1. Language
|
|
1.2. Unit tests
|
|
1.3. CVS
|
|
@@ -18,19 +18,22 @@ quality of the code.
|
|
2.5. Line length
|
|
2.6. Spaces and parentheses
|
|
2.7. End-of-line character
|
|
+ 2.8. Short functions
|
|
+ 2.9. Limit Variable Scope
|
|
3. Naming conventions
|
|
3.1. Classes
|
|
3.2. Variables/parameters/member variables
|
|
3.3. Member variables
|
|
3.4. Files
|
|
3.5. Namespaces
|
|
+ 3.6. Constants
|
|
4. Comments
|
|
5. Miscellaneous
|
|
|
|
|
|
|
|
-1. General guidelines
|
|
-=====================
|
|
+1. General rules
|
|
+================
|
|
|
|
1.1. Language
|
|
-------------
|
|
@@ -50,7 +53,7 @@ When you fix a bug, also add a new test case to ensure the bug will not
|
|
happen anymore.
|
|
|
|
|
|
-1.3. CVS
|
|
+1.3. SVN
|
|
--------
|
|
|
|
Each commit MUST be done with a message ('-m' flag) that briefly describes what
|
|
@@ -154,7 +157,11 @@ Except when body spans over multiple lines:
|
|
2.5. Line length
|
|
----------------
|
|
|
|
-Line length should not exceed 80 characters.
|
|
+Each line of text should not exceed 80 characters.
|
|
+
|
|
+Exception: if a comment line contains an example command or a literal URL
|
|
+longer than 100 characters, that line may be longer than 100 characters
|
|
+for ease of cut and paste.
|
|
|
|
|
|
2.6. Spaces and parentheses
|
|
@@ -193,6 +200,30 @@ Configure your editor to use "\n" (UNIX convention) for end-of-line sequence,
|
|
and not "\r\n" (Windows), nor "\n\r", nor any other combination.
|
|
|
|
|
|
+2.8. Short functions
|
|
+--------------------
|
|
+
|
|
+To the extent that it is feasible, functions should be kept small and focused.
|
|
+It is, however, recognized that long functions are sometimes appropriate, so no
|
|
+hard limit is placed on method length. If a function exceeds 40 lines or so,
|
|
+think about whether it can be broken up without harming the structure of the
|
|
+program.
|
|
+
|
|
+
|
|
+2.9. Limit Variable Scope
|
|
+-------------------------
|
|
+
|
|
+The scope of local variables should be kept to a minimum. By doing so, you
|
|
+increase the readability and maintainability of your code and reduce the
|
|
+likelihood of error. Each variable should be declared in the innermost block
|
|
+that encloses all uses of the variable.
|
|
+
|
|
+Local variables should be declared at the point they are first used. Nearly
|
|
+every local variable declaration should contain an initializer. If you don't
|
|
+yet have enough information to initialize a variable sensibly, you should
|
|
+postpone the declaration until you do.
|
|
+
|
|
+
|
|
|
|
3. Naming conventions
|
|
=====================
|
|
@@ -255,6 +286,12 @@ Implementation files must be placed in 'src/' directory.
|
|
Namespaces are named exactly like variables.
|
|
|
|
|
|
+3.6. Constants
|
|
+--------------
|
|
+
|
|
+Constants are ALL_CAPS_WITH_UNDERSCORES.
|
|
+
|
|
+
|
|
|
|
4. Comments
|
|
===========
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From 130e5223dea0af2f8d9d01cca7845be4e1a08d13 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Thu, 5 Apr 2012 11:46:39 +0200
|
|
Subject: [PATCH 28/39] Added function to retrieve sequence numbers of
|
|
messages whose UID is greater or equal than a
|
|
specified UID (thanks to Zahi Mashael).
|
|
|
|
|
|
diff --git a/src/net/imap/IMAPFolder.cpp b/src/net/imap/IMAPFolder.cpp
|
|
index 0122d21..50a2f2b 100644
|
|
--- a/src/net/imap/IMAPFolder.cpp
|
|
+++ b/src/net/imap/IMAPFolder.cpp
|
|
@@ -1772,6 +1772,62 @@ void IMAPFolder::status(int& count, int& unseen)
|
|
}
|
|
|
|
|
|
+std::vector <int> IMAPFolder::getMessageNumbersStartingOnUID(const message::uid& uid)
|
|
+{
|
|
+ std::vector<int> v;
|
|
+
|
|
+ std::ostringstream command;
|
|
+ command.imbue(std::locale::classic());
|
|
+
|
|
+ command << "SEARCH UID " << uid;
|
|
+
|
|
+ // Send the request
|
|
+ m_connection->send(true, command.str(), true);
|
|
+
|
|
+ // Get the response
|
|
+ utility::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
|
|
+
|
|
+ if (resp->isBad() ||
|
|
+ resp->response_done()->response_tagged()->resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
|
|
+ {
|
|
+ throw exceptions::command_error("SEARCH",
|
|
+ m_connection->getParser()->lastLine(), "bad response");
|
|
+ }
|
|
+
|
|
+ const std::vector <IMAPParser::continue_req_or_response_data*>& respDataList = resp->continue_req_or_response_data();
|
|
+
|
|
+ for (std::vector <IMAPParser::continue_req_or_response_data*>::const_iterator
|
|
+ it = respDataList.begin() ; it != respDataList.end() ; ++it)
|
|
+ {
|
|
+ if ((*it)->response_data() == NULL)
|
|
+ {
|
|
+ throw exceptions::command_error("SEARCH",
|
|
+ m_connection->getParser()->lastLine(), "invalid response");
|
|
+ }
|
|
+
|
|
+ const IMAPParser::mailbox_data* mailboxData =
|
|
+ (*it)->response_data()->mailbox_data();
|
|
+
|
|
+ // We are only interested in responses of type "SEARCH"
|
|
+ if (mailboxData == NULL ||
|
|
+ mailboxData->type() != IMAPParser::mailbox_data::SEARCH)
|
|
+ {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ for (std::vector <IMAPParser::nz_number*>::const_iterator
|
|
+ it = mailboxData->search_nz_number_list().begin() ;
|
|
+ it != mailboxData->search_nz_number_list().end();
|
|
+ ++it)
|
|
+ {
|
|
+ v.push_back((*it)->value());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return v;
|
|
+}
|
|
+
|
|
+
|
|
} // imap
|
|
} // net
|
|
} // vmime
|
|
diff --git a/src/net/maildir/maildirFolder.cpp b/src/net/maildir/maildirFolder.cpp
|
|
index dd680c9..d11ae3b 100644
|
|
--- a/src/net/maildir/maildirFolder.cpp
|
|
+++ b/src/net/maildir/maildirFolder.cpp
|
|
@@ -1363,6 +1363,12 @@ const utility::file::path maildirFolder::getMessageFSPath(const int number) cons
|
|
}
|
|
|
|
|
|
+std::vector <int> maildirFolder::getMessageNumbersStartingOnUID(const message::uid& /* uid */)
|
|
+{
|
|
+ throw exceptions::operation_not_supported();
|
|
+}
|
|
+
|
|
+
|
|
} // maildir
|
|
} // net
|
|
} // vmime
|
|
diff --git a/src/net/pop3/POP3Folder.cpp b/src/net/pop3/POP3Folder.cpp
|
|
index d5fc687..e085609 100644
|
|
--- a/src/net/pop3/POP3Folder.cpp
|
|
+++ b/src/net/pop3/POP3Folder.cpp
|
|
@@ -843,6 +843,12 @@ void POP3Folder::expunge()
|
|
}
|
|
|
|
|
|
+std::vector <int> POP3Folder::getMessageNumbersStartingOnUID(const message::uid& /* uid */)
|
|
+{
|
|
+ throw exceptions::operation_not_supported();
|
|
+}
|
|
+
|
|
+
|
|
} // pop3
|
|
} // net
|
|
} // vmime
|
|
diff --git a/vmime/net/folder.hpp b/vmime/net/folder.hpp
|
|
index b20e9c9..df9cbaf 100644
|
|
--- a/vmime/net/folder.hpp
|
|
+++ b/vmime/net/folder.hpp
|
|
@@ -383,6 +383,13 @@ public:
|
|
*/
|
|
virtual int getFetchCapabilities() const = 0;
|
|
|
|
+ /** Return the sequence numbers of messages whose UID equal or greater than uid
|
|
+ *
|
|
+ * @param uid the uid of the first message
|
|
+ * @throw net_exception if an error occurs
|
|
+ */
|
|
+ virtual std::vector <int> getMessageNumbersStartingOnUID(const message::uid& uid) = 0;
|
|
+
|
|
// Event listeners
|
|
void addMessageChangedListener(events::messageChangedListener* l);
|
|
void removeMessageChangedListener(events::messageChangedListener* l);
|
|
diff --git a/vmime/net/imap/IMAPFolder.hpp b/vmime/net/imap/IMAPFolder.hpp
|
|
index dec3878..cc52596 100644
|
|
--- a/vmime/net/imap/IMAPFolder.hpp
|
|
+++ b/vmime/net/imap/IMAPFolder.hpp
|
|
@@ -120,6 +120,8 @@ public:
|
|
|
|
int getFetchCapabilities() const;
|
|
|
|
+ std::vector <int> getMessageNumbersStartingOnUID(const message::uid& uid);
|
|
+
|
|
private:
|
|
|
|
void registerMessage(IMAPMessage* msg);
|
|
diff --git a/vmime/net/maildir/maildirFolder.hpp b/vmime/net/maildir/maildirFolder.hpp
|
|
index 7474b1a..68b5b89 100644
|
|
--- a/vmime/net/maildir/maildirFolder.hpp
|
|
+++ b/vmime/net/maildir/maildirFolder.hpp
|
|
@@ -121,6 +121,8 @@ public:
|
|
|
|
int getFetchCapabilities() const;
|
|
|
|
+ std::vector <int> getMessageNumbersStartingOnUID(const message::uid& uid);
|
|
+
|
|
private:
|
|
|
|
void scanFolder();
|
|
diff --git a/vmime/net/pop3/POP3Folder.hpp b/vmime/net/pop3/POP3Folder.hpp
|
|
index abaa8eb..c482908 100644
|
|
--- a/vmime/net/pop3/POP3Folder.hpp
|
|
+++ b/vmime/net/pop3/POP3Folder.hpp
|
|
@@ -119,6 +119,8 @@ public:
|
|
|
|
int getFetchCapabilities() const;
|
|
|
|
+ std::vector <int> getMessageNumbersStartingOnUID(const message::uid& uid);
|
|
+
|
|
private:
|
|
|
|
void registerMessage(POP3Message* msg);
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From 3f1a565b8b532f0d11a13d3f6d763b00c8ce625b Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Thu, 5 Apr 2012 11:55:07 +0200
|
|
Subject: [PATCH 29/39] Added .gitignore.
|
|
|
|
|
|
diff --git a/.gitignore b/.gitignore
|
|
new file mode 100644
|
|
index 0000000..44e03a8
|
|
--- /dev/null
|
|
+++ b/.gitignore
|
|
@@ -0,0 +1,11 @@
|
|
+*.o
|
|
+*.swp
|
|
+build/
|
|
+
|
|
+/libvmime.a
|
|
+/vmime.pc
|
|
+/vmime/config.hpp
|
|
+
|
|
+# SConstruct
|
|
+.sconsign.dblite
|
|
+/options.cache
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From 5937bcda0fac9cb80d0cecbaa663ecdfe2839c09 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Thu, 5 Apr 2012 12:08:01 +0200
|
|
Subject: [PATCH 30/39] Added check before dereferencing.
|
|
|
|
|
|
diff --git a/vmime/utility/smartPtr.hpp b/vmime/utility/smartPtr.hpp
|
|
index c448632..df63685 100644
|
|
--- a/vmime/utility/smartPtr.hpp
|
|
+++ b/vmime/utility/smartPtr.hpp
|
|
@@ -338,7 +338,9 @@ protected:
|
|
{
|
|
if (m_ptr)
|
|
{
|
|
- m_ptr->getRefManager()->releaseStrong();
|
|
+ if (m_ptr->getRefManager())
|
|
+ m_ptr->getRefManager()->releaseStrong();
|
|
+
|
|
m_ptr = 0;
|
|
}
|
|
}
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From b0d74ce63ea9563ef4b218bce2497bd668dfad29 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Thu, 5 Apr 2012 12:34:51 +0200
|
|
Subject: [PATCH 31/39] Updated README.
|
|
|
|
|
|
diff --git a/README b/README
|
|
index 6921cea..7db9175 100644
|
|
--- a/README
|
|
+++ b/README
|
|
@@ -1,2 +1,30 @@
|
|
|
|
-TODO
|
|
+VMime is a powerful C++ class library for working with RFC-822 and MIME messages
|
|
+and Internet messaging services like IMAP, POP or SMTP.
|
|
+
|
|
+With VMime you can parse, generate and modify messages, and also connect to store
|
|
+and transport services to receive or send messages over the Internet. The library
|
|
+offers all the features to build a complete mail client.
|
|
+
|
|
+Key Features
|
|
+------------
|
|
+
|
|
+* it is free software! GNU GPL license (Commercial licenses available!)
|
|
+* fully RFC-compliant implementation
|
|
+* object-oriented and modular design
|
|
+* very easy-to-use (intuitive design)
|
|
+* well documented code
|
|
+* very high reliability
|
|
+* maximum portability
|
|
+
|
|
+Features Overview
|
|
+-----------------
|
|
+
|
|
+* RFC-2822 and multipart messages
|
|
+* aggregate documents and embedded objects
|
|
+* 8-bit MIME and encoded word extensions
|
|
+* full support for attachments
|
|
+* POP3, IMAP, SMTP, maildir and sendmail
|
|
+* SSL/TLS security layer and X.509 certificates (using GNU TLS)
|
|
+* SASL authentication (using GNU SASL)
|
|
+
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From 350fada21a4f11c2f633a3cde1f2195efefe7e32 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Thu, 5 Apr 2012 22:10:54 +0200
|
|
Subject: [PATCH 32/39] Added test: Ensure '7bit' encoding is used when body
|
|
is 7-bit only.
|
|
|
|
|
|
diff --git a/tests/parser/bodyPartTest.cpp b/tests/parser/bodyPartTest.cpp
|
|
index 075b8f9..e1d47a3 100644
|
|
--- a/tests/parser/bodyPartTest.cpp
|
|
+++ b/tests/parser/bodyPartTest.cpp
|
|
@@ -37,6 +37,7 @@ VMIME_TEST_SUITE_BEGIN
|
|
VMIME_TEST(testPrologEpilog)
|
|
VMIME_TEST(testPrologEncoding)
|
|
VMIME_TEST(testSuccessiveBoundaries)
|
|
+ VMIME_TEST(testGenerate7bit)
|
|
VMIME_TEST_LIST_END
|
|
|
|
|
|
@@ -200,5 +201,18 @@ VMIME_TEST_SUITE_BEGIN
|
|
VASSERT_EQ("part2-body", "", extractContents(p.getBody()->getPartAt(1)->getBody()->getContents()));
|
|
}
|
|
|
|
+ /** Ensure '7bit' encoding is used when body is 7-bit only. */
|
|
+ void testGenerate7bit()
|
|
+ {
|
|
+ vmime::ref <vmime::plainTextPart> p1 = vmime::create <vmime::plainTextPart>();
|
|
+ p1->setText(vmime::create <vmime::stringContentHandler>("Part1 is US-ASCII only."));
|
|
+
|
|
+ vmime::ref <vmime::message> msg = vmime::create <vmime::message>();
|
|
+ p1->generateIn(msg, msg);
|
|
+
|
|
+ vmime::ref <vmime::header> header1 = msg->getBody()->getPartAt(0)->getHeader();
|
|
+ VASSERT_EQ("1", "7bit", header1->ContentTransferEncoding()->getValue()->generate());
|
|
+ }
|
|
+
|
|
VMIME_TEST_SUITE_END
|
|
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From 6c877ea41a2e408df61ac6f988c3bae7e0821141 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Thu, 5 Apr 2012 22:29:32 +0200
|
|
Subject: [PATCH 33/39] Added tests for Quoted-Printable encoding.
|
|
|
|
|
|
diff --git a/tests/utility/encoderTest.cpp b/tests/utility/encoderTest.cpp
|
|
index f2d42b6..b2d6bc8 100644
|
|
--- a/tests/utility/encoderTest.cpp
|
|
+++ b/tests/utility/encoderTest.cpp
|
|
@@ -33,6 +33,8 @@ VMIME_TEST_SUITE_BEGIN
|
|
VMIME_TEST_LIST_BEGIN
|
|
VMIME_TEST(testBase64)
|
|
VMIME_TEST(testQuotedPrintable)
|
|
+ VMIME_TEST(testQuotedPrintable_SoftLineBreaks)
|
|
+ VMIME_TEST(testQuotedPrintable_CRLF)
|
|
VMIME_TEST(testQuotedPrintable_RFC2047)
|
|
VMIME_TEST_LIST_END
|
|
|
|
@@ -288,6 +290,35 @@ VMIME_TEST_SUITE_BEGIN
|
|
}
|
|
}
|
|
|
|
+ /** Tests Soft Line Breaks (RFC-2047/6.7(5). */
|
|
+ void testQuotedPrintable_SoftLineBreaks()
|
|
+ {
|
|
+ VASSERT_EQ("1", "Now's the time=\r\n"
|
|
+ " for all folk =\r\n"
|
|
+ "to come to the=\r\n"
|
|
+ " aid of their =\r\n"
|
|
+ "country.",
|
|
+ encode("quoted-printable", "Now's the time for all folk "
|
|
+ "to come to the aid of their country.", 15));
|
|
+ }
|
|
+
|
|
+ /** In text mode, ensure line breaks in QP-encoded text are represented
|
|
+ * by a CRLF sequence, as per RFC-2047/6.7(4). */
|
|
+ void testQuotedPrintable_CRLF()
|
|
+ {
|
|
+ vmime::propertySet encProps;
|
|
+
|
|
+ // in "text" mode
|
|
+ encProps["text"] = true;
|
|
+ VASSERT_EQ("text", "line1\r\nline2",
|
|
+ encode("quoted-printable", "line1\r\nline2", 80, encProps));
|
|
+
|
|
+ // in "binary" mode
|
|
+ encProps["text"] = false;
|
|
+ VASSERT_EQ("binary", "line1=0D=0Aline2",
|
|
+ encode("quoted-printable", "line1\r\nline2", 80, encProps));
|
|
+ }
|
|
+
|
|
void testQuotedPrintable_RFC2047()
|
|
{
|
|
/*
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From e88f062ab58654aee3cf45f94e8a5dd6c1256279 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Thu, 5 Apr 2012 23:15:04 +0200
|
|
Subject: [PATCH 34/39] Fixed wrong encoding of line breaks in QP-encoded text
|
|
(issue #7).
|
|
|
|
|
|
diff --git a/src/encoding.cpp b/src/encoding.cpp
|
|
index 0919d44..b4e79db 100644
|
|
--- a/src/encoding.cpp
|
|
+++ b/src/encoding.cpp
|
|
@@ -34,19 +34,28 @@ namespace vmime
|
|
|
|
|
|
encoding::encoding()
|
|
- : m_name(encodingTypes::SEVEN_BIT)
|
|
+ : m_name(encodingTypes::SEVEN_BIT),
|
|
+ m_usage(USAGE_UNKNOWN)
|
|
{
|
|
}
|
|
|
|
|
|
encoding::encoding(const string& name)
|
|
- : m_name(utility::stringUtils::toLower(name))
|
|
+ : m_name(utility::stringUtils::toLower(name)),
|
|
+ m_usage(USAGE_UNKNOWN)
|
|
+{
|
|
+}
|
|
+
|
|
+
|
|
+encoding::encoding(const string& name, const EncodingUsage usage)
|
|
+ : m_name(utility::stringUtils::toLower(name)),
|
|
+ m_usage(usage)
|
|
{
|
|
}
|
|
|
|
|
|
encoding::encoding(const encoding& enc)
|
|
- : headerFieldValue(), m_name(enc.m_name)
|
|
+ : headerFieldValue(), m_name(enc.m_name), m_usage(enc.m_usage)
|
|
{
|
|
}
|
|
|
|
@@ -54,6 +63,8 @@ encoding::encoding(const encoding& enc)
|
|
void encoding::parse(const string& buffer, const string::size_type position,
|
|
const string::size_type end, string::size_type* newPosition)
|
|
{
|
|
+ m_usage = USAGE_UNKNOWN;
|
|
+
|
|
m_name = utility::stringUtils::toLower(utility::stringUtils::trim
|
|
(utility::stringUtils::unquote(utility::stringUtils::trim
|
|
(string(buffer.begin() + position, buffer.begin() + end)))));
|
|
@@ -80,7 +91,14 @@ void encoding::generate(utility::outputStream& os, const string::size_type /* ma
|
|
|
|
ref <utility::encoder::encoder> encoding::getEncoder() const
|
|
{
|
|
- return (utility::encoder::encoderFactory::getInstance()->create(generate()));
|
|
+ ref <utility::encoder::encoder> encoder =
|
|
+ utility::encoder::encoderFactory::getInstance()->create(generate());
|
|
+
|
|
+ // FIXME: this should not be here (move me into QP encoder instead?)
|
|
+ if (m_usage == USAGE_TEXT && m_name == encodingTypes::QUOTED_PRINTABLE)
|
|
+ encoder->getProperties()["text"] = true;
|
|
+
|
|
+ return encoder;
|
|
}
|
|
|
|
|
|
@@ -94,6 +112,7 @@ encoding& encoding::operator=(const encoding& other)
|
|
encoding& encoding::operator=(const string& name)
|
|
{
|
|
m_name = utility::stringUtils::toLower(name);
|
|
+ m_usage = USAGE_UNKNOWN;
|
|
return (*this);
|
|
}
|
|
|
|
@@ -167,6 +186,8 @@ const encoding encoding::decideImpl
|
|
const encoding encoding::decide
|
|
(ref <const contentHandler> data, const EncodingUsage usage)
|
|
{
|
|
+ encoding enc;
|
|
+
|
|
if (usage == USAGE_TEXT && data->isBuffered() &&
|
|
data->getLength() > 0 && data->getLength() < 32768)
|
|
{
|
|
@@ -177,12 +198,16 @@ const encoding encoding::decide
|
|
data->extract(os);
|
|
os.flush();
|
|
|
|
- return decideImpl(buffer.begin(), buffer.end());
|
|
+ enc = decideImpl(buffer.begin(), buffer.end());
|
|
}
|
|
else
|
|
{
|
|
- return encoding(encodingTypes::BASE64);
|
|
+ enc = encoding(encodingTypes::BASE64);
|
|
}
|
|
+
|
|
+ enc.setUsage(usage);
|
|
+
|
|
+ return enc;
|
|
}
|
|
|
|
|
|
@@ -194,7 +219,10 @@ const encoding encoding::decide(ref <const contentHandler> data,
|
|
encoding recEncoding;
|
|
|
|
if (chset.getRecommendedEncoding(recEncoding))
|
|
+ {
|
|
+ recEncoding.setUsage(usage);
|
|
return recEncoding;
|
|
+ }
|
|
}
|
|
|
|
return decide(data, usage);
|
|
@@ -227,6 +255,18 @@ void encoding::setName(const string& name)
|
|
}
|
|
|
|
|
|
+encoding::EncodingUsage encoding::getUsage() const
|
|
+{
|
|
+ return m_usage;
|
|
+}
|
|
+
|
|
+
|
|
+void encoding::setUsage(const EncodingUsage usage)
|
|
+{
|
|
+ m_usage = usage;
|
|
+}
|
|
+
|
|
+
|
|
const std::vector <ref <const component> > encoding::getChildComponents() const
|
|
{
|
|
return std::vector <ref <const component> >();
|
|
diff --git a/src/utility/encoder/qpEncoder.cpp b/src/utility/encoder/qpEncoder.cpp
|
|
index aa95022..ab8db2e 100644
|
|
--- a/src/utility/encoder/qpEncoder.cpp
|
|
+++ b/src/utility/encoder/qpEncoder.cpp
|
|
@@ -292,14 +292,15 @@ utility::stream::size_type qpEncoder::encode(utility::inputStream& in,
|
|
case 13: // CR
|
|
case 10: // LF
|
|
{
|
|
- // Text mode (where using CRLF or LF or ... does not
|
|
- // care for a new line...)
|
|
- if (text)
|
|
+ // RFC-2045/6.7(4)
|
|
+
|
|
+ // Text data
|
|
+ if (text && !rfc2047)
|
|
{
|
|
outBuffer[outBufferPos++] = c;
|
|
++curCol;
|
|
}
|
|
- // Binary mode (where CR and LF bytes are important!)
|
|
+ // Binary data
|
|
else
|
|
{
|
|
QP_ENCODE_HEX(c);
|
|
diff --git a/tests/parser/bodyPartTest.cpp b/tests/parser/bodyPartTest.cpp
|
|
index e1d47a3..9d51262 100644
|
|
--- a/tests/parser/bodyPartTest.cpp
|
|
+++ b/tests/parser/bodyPartTest.cpp
|
|
@@ -38,6 +38,7 @@ VMIME_TEST_SUITE_BEGIN
|
|
VMIME_TEST(testPrologEncoding)
|
|
VMIME_TEST(testSuccessiveBoundaries)
|
|
VMIME_TEST(testGenerate7bit)
|
|
+ VMIME_TEST(testTextUsageForQPEncoding)
|
|
VMIME_TEST_LIST_END
|
|
|
|
|
|
@@ -214,5 +215,28 @@ VMIME_TEST_SUITE_BEGIN
|
|
VASSERT_EQ("1", "7bit", header1->ContentTransferEncoding()->getValue()->generate());
|
|
}
|
|
|
|
+ void testTextUsageForQPEncoding()
|
|
+ {
|
|
+ vmime::ref <vmime::plainTextPart> part = vmime::create <vmime::plainTextPart>();
|
|
+ part->setText(vmime::create <vmime::stringContentHandler>("Part1-line1\r\nPart1-line2\r\n\x89"));
|
|
+
|
|
+ vmime::ref <vmime::message> msg = vmime::create <vmime::message>();
|
|
+ part->generateIn(msg, msg);
|
|
+
|
|
+ vmime::ref <vmime::body> body = msg->getBody()->getPartAt(0)->getBody();
|
|
+ vmime::ref <vmime::header> header = msg->getBody()->getPartAt(0)->getHeader();
|
|
+
|
|
+ std::ostringstream oss;
|
|
+ vmime::utility::outputStreamAdapter os(oss);
|
|
+ body->generate(os, 80);
|
|
+
|
|
+ VASSERT_EQ("1", "quoted-printable", header->ContentTransferEncoding()->getValue()->generate());
|
|
+
|
|
+ // This should *NOT* be:
|
|
+ // Part1-line1=0D=0APart1-line2=0D=0A=89
|
|
+ VASSERT_EQ("2", "Part1-line1\r\nPart1-line2\r\n=89", oss.str());
|
|
+ }
|
|
+
|
|
+
|
|
VMIME_TEST_SUITE_END
|
|
|
|
diff --git a/vmime/encoding.hpp b/vmime/encoding.hpp
|
|
index ba78081..42f5246 100644
|
|
--- a/vmime/encoding.hpp
|
|
+++ b/vmime/encoding.hpp
|
|
@@ -47,6 +47,7 @@ public:
|
|
|
|
enum EncodingUsage
|
|
{
|
|
+ USAGE_UNKNOWN,
|
|
USAGE_TEXT, /**< Use for body text. */
|
|
USAGE_BINARY_DATA /**< Use for attachment, image... */
|
|
};
|
|
@@ -54,6 +55,7 @@ public:
|
|
|
|
encoding();
|
|
explicit encoding(const string& name);
|
|
+ encoding(const string& name, const EncodingUsage usage);
|
|
encoding(const encoding& enc);
|
|
|
|
public:
|
|
@@ -72,6 +74,19 @@ public:
|
|
*/
|
|
void setName(const string& name);
|
|
|
|
+ /** Return the type of contents this encoding is used for.
|
|
+ * See the EncodingUsage enum.
|
|
+ */
|
|
+ EncodingUsage getUsage() const;
|
|
+
|
|
+ /** Set the type of contents this encoding is used for.
|
|
+ * See the EncodingUsage enum.
|
|
+ *
|
|
+ * @param usage type of contents
|
|
+ */
|
|
+ void setUsage(const EncodingUsage usage);
|
|
+
|
|
+
|
|
encoding& operator=(const encoding& other);
|
|
encoding& operator=(const string& name);
|
|
|
|
@@ -113,6 +128,7 @@ public:
|
|
private:
|
|
|
|
string m_name;
|
|
+ EncodingUsage m_usage;
|
|
|
|
/** Decide which encoding to use based on the specified data.
|
|
*
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From ea77bdba96588345090e3de81d9d6af116edeeb5 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Fri, 6 Apr 2012 22:26:18 +0200
|
|
Subject: [PATCH 35/39] Fixed memory leak.
|
|
|
|
|
|
diff --git a/src/net/tls/TLSSocket.cpp b/src/net/tls/TLSSocket.cpp
|
|
index dab0338..3cccc1e 100644
|
|
--- a/src/net/tls/TLSSocket.cpp
|
|
+++ b/src/net/tls/TLSSocket.cpp
|
|
@@ -50,6 +50,12 @@ TLSSocket::TLSSocket(ref <TLSSession> session, ref <socket> sok)
|
|
|
|
TLSSocket::~TLSSocket()
|
|
{
|
|
+ if (m_ex)
|
|
+ {
|
|
+ delete m_ex;
|
|
+ m_ex = NULL;
|
|
+ }
|
|
+
|
|
try
|
|
{
|
|
disconnect();
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From 440d491fd6da134fcb5f19416743e8f2044556bf Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Sat, 14 Apr 2012 13:46:05 +0200
|
|
Subject: [PATCH 36/39] Split stream.hpp/.cpp into multiple source files.
|
|
|
|
|
|
diff --git a/SConstruct b/SConstruct
|
|
index 11e884b..ea5c4eb 100644
|
|
--- a/SConstruct
|
|
+++ b/SConstruct
|
|
@@ -144,6 +144,20 @@ libvmime_sources = [
|
|
'utility/smartPtr.cpp', 'utility/smartPtr.hpp',
|
|
'utility/smartPtrInt.cpp', 'utility/smartPtrInt.hpp',
|
|
'utility/stream.cpp', 'utility/stream.hpp',
|
|
+ 'utility/streamUtils.cpp', 'utility/streamUtils.hpp',
|
|
+ 'utility/filteredStream.cpp', 'utility/filteredStream.hpp',
|
|
+ 'utility/inputStream.cpp', 'utility/inputStream.hpp',
|
|
+ 'utility/inputStreamAdapter.cpp', 'utility/inputStreamAdapter.hpp',
|
|
+ 'utility/inputStreamByteBufferAdapter.cpp', 'utility/inputStreamByteBufferAdapter.hpp',
|
|
+ 'utility/inputStreamPointerAdapter.cpp', 'utility/inputStreamPointerAdapter.hpp',
|
|
+ 'utility/inputStreamSocketAdapter.cpp', 'utility/inputStreamSocketAdapter.hpp',
|
|
+ 'utility/inputStreamStringAdapter.cpp', 'utility/inputStreamStringAdapter.hpp',
|
|
+ 'utility/inputStreamStringProxyAdapter.cpp', 'utility/inputStreamStringProxyAdapter.hpp',
|
|
+ 'utility/outputStream.cpp', 'utility/outputStream.hpp',
|
|
+ 'utility/outputStreamAdapter.cpp', 'utility/outputStreamAdapter.hpp',
|
|
+ 'utility/outputStreamByteArrayAdapter.cpp', 'utility/outputStreamByteArrayAdapter.hpp',
|
|
+ 'utility/outputStreamSocketAdapter.cpp', 'utility/outputStreamSocketAdapter.hpp',
|
|
+ 'utility/outputStreamStringAdapter.cpp', 'utility/outputStreamStringAdapter.hpp',
|
|
'utility/stringProxy.cpp', 'utility/stringProxy.hpp',
|
|
'utility/stringUtils.cpp', 'utility/stringUtils.hpp',
|
|
'utility/url.cpp', 'utility/url.hpp',
|
|
diff --git a/src/charsetConverter.cpp b/src/charsetConverter.cpp
|
|
index 2135788..cf75bdd 100644
|
|
--- a/src/charsetConverter.cpp
|
|
+++ b/src/charsetConverter.cpp
|
|
@@ -23,6 +23,8 @@
|
|
|
|
#include "vmime/charsetConverter.hpp"
|
|
#include "vmime/exception.hpp"
|
|
+#include "vmime/utility/inputStreamStringAdapter.hpp"
|
|
+#include "vmime/utility/outputStreamStringAdapter.hpp"
|
|
|
|
|
|
extern "C"
|
|
diff --git a/src/component.cpp b/src/component.cpp
|
|
index fbf677b..139cf66 100644
|
|
--- a/src/component.cpp
|
|
+++ b/src/component.cpp
|
|
@@ -23,6 +23,7 @@
|
|
|
|
#include "vmime/component.hpp"
|
|
#include "vmime/base.hpp"
|
|
+#include "vmime/utility/outputStreamAdapter.hpp"
|
|
|
|
#include <sstream>
|
|
|
|
diff --git a/src/encoding.cpp b/src/encoding.cpp
|
|
index b4e79db..5d99ab6 100644
|
|
--- a/src/encoding.cpp
|
|
+++ b/src/encoding.cpp
|
|
@@ -24,6 +24,7 @@
|
|
#include "vmime/encoding.hpp"
|
|
#include "vmime/contentHandler.hpp"
|
|
|
|
+#include "vmime/utility/outputStreamStringAdapter.hpp"
|
|
#include "vmime/utility/encoder/encoderFactory.hpp"
|
|
|
|
#include <algorithm>
|
|
diff --git a/src/fileAttachment.cpp b/src/fileAttachment.cpp
|
|
index da7c4b7..cb23cd0 100644
|
|
--- a/src/fileAttachment.cpp
|
|
+++ b/src/fileAttachment.cpp
|
|
@@ -28,6 +28,7 @@
|
|
#include "vmime/exception.hpp"
|
|
|
|
#include "vmime/streamContentHandler.hpp"
|
|
+#include "vmime/utility/inputStreamPointerAdapter.hpp"
|
|
|
|
#include "vmime/contentDispositionField.hpp"
|
|
|
|
diff --git a/src/generatedMessageAttachment.cpp b/src/generatedMessageAttachment.cpp
|
|
index e9bd1a6..443a9d3 100644
|
|
--- a/src/generatedMessageAttachment.cpp
|
|
+++ b/src/generatedMessageAttachment.cpp
|
|
@@ -23,6 +23,8 @@
|
|
|
|
#include "vmime/generatedMessageAttachment.hpp"
|
|
|
|
+#include "vmime/utility/outputStreamAdapter.hpp"
|
|
+
|
|
|
|
namespace vmime
|
|
{
|
|
diff --git a/src/htmlTextPart.cpp b/src/htmlTextPart.cpp
|
|
index c845b57..98524af 100644
|
|
--- a/src/htmlTextPart.cpp
|
|
+++ b/src/htmlTextPart.cpp
|
|
@@ -31,6 +31,8 @@
|
|
#include "vmime/emptyContentHandler.hpp"
|
|
#include "vmime/stringContentHandler.hpp"
|
|
|
|
+#include "vmime/utility/outputStreamAdapter.hpp"
|
|
+
|
|
|
|
namespace vmime
|
|
{
|
|
diff --git a/src/mdn/MDNHelper.cpp b/src/mdn/MDNHelper.cpp
|
|
index b419b85..1dd7ff3 100644
|
|
--- a/src/mdn/MDNHelper.cpp
|
|
+++ b/src/mdn/MDNHelper.cpp
|
|
@@ -31,6 +31,8 @@
|
|
#include "vmime/path.hpp"
|
|
#include "vmime/dateTime.hpp"
|
|
|
|
+#include "vmime/utility/outputStreamAdapter.hpp"
|
|
+
|
|
|
|
namespace vmime {
|
|
namespace mdn {
|
|
diff --git a/src/mdn/receivedMDNInfos.cpp b/src/mdn/receivedMDNInfos.cpp
|
|
index cff211c..f97a58d 100644
|
|
--- a/src/mdn/receivedMDNInfos.cpp
|
|
+++ b/src/mdn/receivedMDNInfos.cpp
|
|
@@ -23,6 +23,8 @@
|
|
|
|
#include "vmime/mdn/receivedMDNInfos.hpp"
|
|
|
|
+#include "vmime/utility/outputStreamAdapter.hpp"
|
|
+
|
|
|
|
namespace vmime {
|
|
namespace mdn {
|
|
diff --git a/src/message.cpp b/src/message.cpp
|
|
index 6f4b046..1b4f086 100644
|
|
--- a/src/message.cpp
|
|
+++ b/src/message.cpp
|
|
@@ -24,6 +24,8 @@
|
|
#include "vmime/message.hpp"
|
|
#include "vmime/options.hpp"
|
|
|
|
+#include "vmime/utility/outputStreamAdapter.hpp"
|
|
+
|
|
#include <sstream>
|
|
|
|
|
|
diff --git a/src/net/imap/IMAPFolder.cpp b/src/net/imap/IMAPFolder.cpp
|
|
index 50a2f2b..81bf386 100644
|
|
--- a/src/net/imap/IMAPFolder.cpp
|
|
+++ b/src/net/imap/IMAPFolder.cpp
|
|
@@ -34,6 +34,8 @@
|
|
#include "vmime/exception.hpp"
|
|
#include "vmime/utility/smartPtr.hpp"
|
|
|
|
+#include "vmime/utility/outputStreamAdapter.hpp"
|
|
+
|
|
#include <algorithm>
|
|
#include <sstream>
|
|
|
|
diff --git a/src/net/imap/IMAPMessage.cpp b/src/net/imap/IMAPMessage.cpp
|
|
index bc661ed..702d5f2 100644
|
|
--- a/src/net/imap/IMAPMessage.cpp
|
|
+++ b/src/net/imap/IMAPMessage.cpp
|
|
@@ -31,6 +31,8 @@
|
|
#include "vmime/net/imap/IMAPPart.hpp"
|
|
#include "vmime/net/imap/IMAPMessagePartContentHandler.hpp"
|
|
|
|
+#include "vmime/utility/outputStreamAdapter.hpp"
|
|
+
|
|
#include <sstream>
|
|
#include <iterator>
|
|
#include <typeinfo>
|
|
diff --git a/src/net/imap/IMAPMessagePartContentHandler.cpp b/src/net/imap/IMAPMessagePartContentHandler.cpp
|
|
index 4e6ba97..85c6ec2 100644
|
|
--- a/src/net/imap/IMAPMessagePartContentHandler.cpp
|
|
+++ b/src/net/imap/IMAPMessagePartContentHandler.cpp
|
|
@@ -23,6 +23,9 @@
|
|
|
|
#include "vmime/net/imap/IMAPMessagePartContentHandler.hpp"
|
|
|
|
+#include "vmime/utility/outputStreamAdapter.hpp"
|
|
+#include "vmime/utility/inputStreamStringProxyAdapter.hpp"
|
|
+
|
|
|
|
namespace vmime {
|
|
namespace net {
|
|
diff --git a/src/net/maildir/maildirFolder.cpp b/src/net/maildir/maildirFolder.cpp
|
|
index d11ae3b..8c4b275 100644
|
|
--- a/src/net/maildir/maildirFolder.cpp
|
|
+++ b/src/net/maildir/maildirFolder.cpp
|
|
@@ -35,6 +35,9 @@
|
|
#include "vmime/exception.hpp"
|
|
#include "vmime/platform.hpp"
|
|
|
|
+#include "vmime/utility/outputStreamAdapter.hpp"
|
|
+#include "vmime/utility/inputStreamStringAdapter.hpp"
|
|
+
|
|
|
|
namespace vmime {
|
|
namespace net {
|
|
diff --git a/src/net/maildir/maildirMessage.cpp b/src/net/maildir/maildirMessage.cpp
|
|
index 51cd1ba..4ab75e7 100644
|
|
--- a/src/net/maildir/maildirMessage.cpp
|
|
+++ b/src/net/maildir/maildirMessage.cpp
|
|
@@ -31,6 +31,8 @@
|
|
#include "vmime/exception.hpp"
|
|
#include "vmime/platform.hpp"
|
|
|
|
+#include "vmime/utility/outputStreamAdapter.hpp"
|
|
+
|
|
|
|
namespace vmime {
|
|
namespace net {
|
|
diff --git a/src/net/pop3/POP3Message.cpp b/src/net/pop3/POP3Message.cpp
|
|
index 50f4f87..69ef004 100644
|
|
--- a/src/net/pop3/POP3Message.cpp
|
|
+++ b/src/net/pop3/POP3Message.cpp
|
|
@@ -25,6 +25,8 @@
|
|
#include "vmime/net/pop3/POP3Folder.hpp"
|
|
#include "vmime/net/pop3/POP3Store.hpp"
|
|
|
|
+#include "vmime/utility/outputStreamAdapter.hpp"
|
|
+
|
|
#include <sstream>
|
|
|
|
|
|
diff --git a/src/net/pop3/POP3Store.cpp b/src/net/pop3/POP3Store.cpp
|
|
index 9d554c6..793112a 100644
|
|
--- a/src/net/pop3/POP3Store.cpp
|
|
+++ b/src/net/pop3/POP3Store.cpp
|
|
@@ -30,6 +30,7 @@
|
|
#include "vmime/security/digest/messageDigestFactory.hpp"
|
|
#include "vmime/utility/filteredStream.hpp"
|
|
#include "vmime/utility/stringUtils.hpp"
|
|
+#include "vmime/utility/inputStreamSocketAdapter.hpp"
|
|
|
|
#include "vmime/net/defaultConnectionInfos.hpp"
|
|
|
|
diff --git a/src/net/sendmail/sendmailTransport.cpp b/src/net/sendmail/sendmailTransport.cpp
|
|
index 53ff0d1..e7762cc 100644
|
|
--- a/src/net/sendmail/sendmailTransport.cpp
|
|
+++ b/src/net/sendmail/sendmailTransport.cpp
|
|
@@ -32,6 +32,8 @@
|
|
#include "vmime/utility/childProcess.hpp"
|
|
#include "vmime/utility/smartPtr.hpp"
|
|
|
|
+#include "vmime/utility/streamUtils.hpp"
|
|
+
|
|
#include "vmime/net/defaultConnectionInfos.hpp"
|
|
|
|
#include "vmime/config.hpp"
|
|
diff --git a/src/net/smtp/SMTPTransport.cpp b/src/net/smtp/SMTPTransport.cpp
|
|
index d9fb7b8..bbbea75 100644
|
|
--- a/src/net/smtp/SMTPTransport.cpp
|
|
+++ b/src/net/smtp/SMTPTransport.cpp
|
|
@@ -30,6 +30,8 @@
|
|
|
|
#include "vmime/utility/filteredStream.hpp"
|
|
#include "vmime/utility/stringUtils.hpp"
|
|
+#include "vmime/utility/outputStreamSocketAdapter.hpp"
|
|
+#include "vmime/utility/streamUtils.hpp"
|
|
|
|
#include "vmime/net/defaultConnectionInfos.hpp"
|
|
|
|
diff --git a/src/net/transport.cpp b/src/net/transport.cpp
|
|
index dd4663d..f8ca7b7 100644
|
|
--- a/src/net/transport.cpp
|
|
+++ b/src/net/transport.cpp
|
|
@@ -27,6 +27,9 @@
|
|
#include "vmime/mailboxList.hpp"
|
|
#include "vmime/message.hpp"
|
|
|
|
+#include "vmime/utility/outputStreamAdapter.hpp"
|
|
+#include "vmime/utility/inputStreamStringAdapter.hpp"
|
|
+
|
|
|
|
namespace vmime {
|
|
namespace net {
|
|
diff --git a/src/parameter.cpp b/src/parameter.cpp
|
|
index d757e1b..ccbe1a5 100644
|
|
--- a/src/parameter.cpp
|
|
+++ b/src/parameter.cpp
|
|
@@ -27,6 +27,9 @@
|
|
#include "vmime/text.hpp"
|
|
#include "vmime/encoding.hpp"
|
|
|
|
+#include "vmime/utility/outputStreamAdapter.hpp"
|
|
+#include "vmime/utility/outputStreamStringAdapter.hpp"
|
|
+
|
|
|
|
namespace vmime
|
|
{
|
|
diff --git a/src/parsedMessageAttachment.cpp b/src/parsedMessageAttachment.cpp
|
|
index bde56aa..cb7d71d 100644
|
|
--- a/src/parsedMessageAttachment.cpp
|
|
+++ b/src/parsedMessageAttachment.cpp
|
|
@@ -26,6 +26,8 @@
|
|
#include "vmime/stringContentHandler.hpp"
|
|
#include "vmime/contentDisposition.hpp"
|
|
|
|
+#include "vmime/utility/outputStreamAdapter.hpp"
|
|
+
|
|
|
|
namespace vmime
|
|
{
|
|
diff --git a/src/security/cert/X509Certificate.cpp b/src/security/cert/X509Certificate.cpp
|
|
index 1cd079c..8df4e5e 100644
|
|
--- a/src/security/cert/X509Certificate.cpp
|
|
+++ b/src/security/cert/X509Certificate.cpp
|
|
@@ -28,6 +28,8 @@
|
|
|
|
#include "vmime/security/cert/X509Certificate.hpp"
|
|
|
|
+#include "vmime/utility/outputStreamByteArrayAdapter.hpp"
|
|
+
|
|
|
|
namespace vmime {
|
|
namespace security {
|
|
diff --git a/src/security/sasl/SASLContext.cpp b/src/security/sasl/SASLContext.cpp
|
|
index 51c2bed..4bb33c1 100644
|
|
--- a/src/security/sasl/SASLContext.cpp
|
|
+++ b/src/security/sasl/SASLContext.cpp
|
|
@@ -33,6 +33,9 @@
|
|
#include "vmime/utility/encoder/encoderFactory.hpp"
|
|
|
|
#include "vmime/utility/stream.hpp"
|
|
+#include "vmime/utility/outputStreamStringAdapter.hpp"
|
|
+#include "vmime/utility/inputStreamStringAdapter.hpp"
|
|
+#include "vmime/utility/inputStreamByteBufferAdapter.hpp"
|
|
|
|
|
|
namespace vmime {
|
|
diff --git a/src/streamContentHandler.cpp b/src/streamContentHandler.cpp
|
|
index 2ebd073..89a36b4 100644
|
|
--- a/src/streamContentHandler.cpp
|
|
+++ b/src/streamContentHandler.cpp
|
|
@@ -23,6 +23,10 @@
|
|
|
|
#include "vmime/streamContentHandler.hpp"
|
|
|
|
+#include "vmime/utility/outputStreamAdapter.hpp"
|
|
+#include "vmime/utility/inputStreamStringAdapter.hpp"
|
|
+#include "vmime/utility/streamUtils.hpp"
|
|
+
|
|
|
|
namespace vmime
|
|
{
|
|
diff --git a/src/stringContentHandler.cpp b/src/stringContentHandler.cpp
|
|
index 4e85a6c..5a1e72c 100644
|
|
--- a/src/stringContentHandler.cpp
|
|
+++ b/src/stringContentHandler.cpp
|
|
@@ -23,6 +23,10 @@
|
|
|
|
#include "vmime/stringContentHandler.hpp"
|
|
|
|
+#include "vmime/utility/inputStreamStringAdapter.hpp"
|
|
+#include "vmime/utility/inputStreamStringProxyAdapter.hpp"
|
|
+#include "vmime/utility/outputStreamAdapter.hpp"
|
|
+
|
|
|
|
namespace vmime
|
|
{
|
|
diff --git a/src/utility/encoder/defaultEncoder.cpp b/src/utility/encoder/defaultEncoder.cpp
|
|
index 4d0ffb5..e2d226e 100644
|
|
--- a/src/utility/encoder/defaultEncoder.cpp
|
|
+++ b/src/utility/encoder/defaultEncoder.cpp
|
|
@@ -23,6 +23,8 @@
|
|
|
|
#include "vmime/utility/encoder/defaultEncoder.hpp"
|
|
|
|
+#include "vmime/utility/streamUtils.hpp"
|
|
+
|
|
|
|
namespace vmime {
|
|
namespace utility {
|
|
diff --git a/src/utility/inputStream.cpp b/src/utility/inputStream.cpp
|
|
new file mode 100644
|
|
index 0000000..dd0adf4
|
|
--- /dev/null
|
|
+++ b/src/utility/inputStream.cpp
|
|
@@ -0,0 +1,33 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#include "vmime/utility/inputStream.hpp"
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
diff --git a/src/utility/inputStreamAdapter.cpp b/src/utility/inputStreamAdapter.cpp
|
|
new file mode 100644
|
|
index 0000000..b44b084
|
|
--- /dev/null
|
|
+++ b/src/utility/inputStreamAdapter.cpp
|
|
@@ -0,0 +1,70 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#include "vmime/utility/inputStreamAdapter.hpp"
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+inputStreamAdapter::inputStreamAdapter(std::istream& is)
|
|
+ : m_stream(is)
|
|
+{
|
|
+}
|
|
+
|
|
+
|
|
+bool inputStreamAdapter::eof() const
|
|
+{
|
|
+ return (m_stream.eof());
|
|
+}
|
|
+
|
|
+
|
|
+void inputStreamAdapter::reset()
|
|
+{
|
|
+ m_stream.exceptions(std::ios_base::badbit);
|
|
+ m_stream.seekg(0, std::ios::beg);
|
|
+ m_stream.clear();
|
|
+}
|
|
+
|
|
+
|
|
+stream::size_type inputStreamAdapter::read
|
|
+ (value_type* const data, const size_type count)
|
|
+{
|
|
+ m_stream.exceptions(std::ios_base::badbit);
|
|
+ m_stream.read(data, count);
|
|
+ return (m_stream.gcount());
|
|
+}
|
|
+
|
|
+
|
|
+stream::size_type inputStreamAdapter::skip(const size_type count)
|
|
+{
|
|
+ m_stream.exceptions(std::ios_base::badbit);
|
|
+ m_stream.ignore(count);
|
|
+ return (m_stream.gcount());
|
|
+}
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
diff --git a/src/utility/inputStreamByteBufferAdapter.cpp b/src/utility/inputStreamByteBufferAdapter.cpp
|
|
new file mode 100644
|
|
index 0000000..92e779f
|
|
--- /dev/null
|
|
+++ b/src/utility/inputStreamByteBufferAdapter.cpp
|
|
@@ -0,0 +1,90 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#include "vmime/utility/inputStreamByteBufferAdapter.hpp"
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+inputStreamByteBufferAdapter::inputStreamByteBufferAdapter(const byte_t* buffer, const size_type length)
|
|
+ : m_buffer(buffer), m_length(length), m_pos(0)
|
|
+{
|
|
+}
|
|
+
|
|
+
|
|
+bool inputStreamByteBufferAdapter::eof() const
|
|
+{
|
|
+ return m_pos >= m_length;
|
|
+}
|
|
+
|
|
+
|
|
+void inputStreamByteBufferAdapter::reset()
|
|
+{
|
|
+ m_pos = 0;
|
|
+}
|
|
+
|
|
+
|
|
+stream::size_type inputStreamByteBufferAdapter::read
|
|
+ (value_type* const data, const size_type count)
|
|
+{
|
|
+ const size_type remaining = m_length - m_pos;
|
|
+
|
|
+ if (remaining < count)
|
|
+ {
|
|
+ std::copy(m_buffer + m_pos, m_buffer + m_pos + remaining, data);
|
|
+ m_pos += remaining;
|
|
+
|
|
+ return remaining;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ std::copy(m_buffer + m_pos, m_buffer + m_pos + count, data);
|
|
+ m_pos += count;
|
|
+
|
|
+ return count;
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+stream::size_type inputStreamByteBufferAdapter::skip(const size_type count)
|
|
+{
|
|
+ const size_type remaining = m_length - m_pos;
|
|
+
|
|
+ if (remaining < count)
|
|
+ {
|
|
+ m_pos += remaining;
|
|
+ return remaining;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ m_pos += count;
|
|
+ return count;
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
diff --git a/src/utility/inputStreamPointerAdapter.cpp b/src/utility/inputStreamPointerAdapter.cpp
|
|
new file mode 100644
|
|
index 0000000..4d03e30
|
|
--- /dev/null
|
|
+++ b/src/utility/inputStreamPointerAdapter.cpp
|
|
@@ -0,0 +1,46 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#include "vmime/utility/inputStreamPointerAdapter.hpp"
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+inputStreamPointerAdapter::inputStreamPointerAdapter(std::istream* is, const bool own)
|
|
+ : inputStreamAdapter(*is), m_stream(is), m_own(own)
|
|
+{
|
|
+}
|
|
+
|
|
+
|
|
+inputStreamPointerAdapter::~inputStreamPointerAdapter()
|
|
+{
|
|
+ if (m_own)
|
|
+ delete (m_stream);
|
|
+}
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
diff --git a/src/utility/inputStreamSocketAdapter.cpp b/src/utility/inputStreamSocketAdapter.cpp
|
|
new file mode 100644
|
|
index 0000000..b93cc3c
|
|
--- /dev/null
|
|
+++ b/src/utility/inputStreamSocketAdapter.cpp
|
|
@@ -0,0 +1,82 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#include "vmime/utility/inputStreamSocketAdapter.hpp"
|
|
+
|
|
+
|
|
+#if VMIME_HAVE_MESSAGING_FEATURES
|
|
+
|
|
+
|
|
+#include "vmime/net/socket.hpp"
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+inputStreamSocketAdapter::inputStreamSocketAdapter(net::socket& sok)
|
|
+ : m_socket(sok)
|
|
+{
|
|
+}
|
|
+
|
|
+
|
|
+bool inputStreamSocketAdapter::eof() const
|
|
+{
|
|
+ // Can't know...
|
|
+ return false;
|
|
+}
|
|
+
|
|
+
|
|
+void inputStreamSocketAdapter::reset()
|
|
+{
|
|
+ // Not supported
|
|
+}
|
|
+
|
|
+
|
|
+stream::size_type inputStreamSocketAdapter::read
|
|
+ (value_type* const data, const size_type count)
|
|
+{
|
|
+ return m_socket.receiveRaw(data, count);
|
|
+}
|
|
+
|
|
+
|
|
+stream::size_type inputStreamSocketAdapter::skip
|
|
+ (const size_type /* count */)
|
|
+{
|
|
+ // Not supported
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+stream::size_type inputStreamSocketAdapter::getBlockSize()
|
|
+{
|
|
+ return m_socket.getBlockSize();
|
|
+}
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
+
|
|
+#endif // VMIME_HAVE_MESSAGING_FEATURES
|
|
+
|
|
diff --git a/src/utility/inputStreamStringAdapter.cpp b/src/utility/inputStreamStringAdapter.cpp
|
|
new file mode 100644
|
|
index 0000000..31c9fda
|
|
--- /dev/null
|
|
+++ b/src/utility/inputStreamStringAdapter.cpp
|
|
@@ -0,0 +1,94 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#include "vmime/utility/inputStreamStringAdapter.hpp"
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+inputStreamStringAdapter::inputStreamStringAdapter(const string& buffer)
|
|
+ : m_buffer(buffer), m_begin(0), m_end(buffer.length()), m_pos(0)
|
|
+{
|
|
+}
|
|
+
|
|
+
|
|
+inputStreamStringAdapter::inputStreamStringAdapter(const string& buffer,
|
|
+ const string::size_type begin, const string::size_type end)
|
|
+ : m_buffer(buffer), m_begin(begin), m_end(end), m_pos(begin)
|
|
+{
|
|
+}
|
|
+
|
|
+
|
|
+bool inputStreamStringAdapter::eof() const
|
|
+{
|
|
+ return (m_pos >= m_end);
|
|
+}
|
|
+
|
|
+
|
|
+void inputStreamStringAdapter::reset()
|
|
+{
|
|
+ m_pos = m_begin;
|
|
+}
|
|
+
|
|
+
|
|
+stream::size_type inputStreamStringAdapter::read
|
|
+ (value_type* const data, const size_type count)
|
|
+{
|
|
+ if (m_pos + count >= m_end)
|
|
+ {
|
|
+ const size_type remaining = m_end - m_pos;
|
|
+
|
|
+ std::copy(m_buffer.begin() + m_pos, m_buffer.end(), data);
|
|
+ m_pos = m_end;
|
|
+ return (remaining);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ std::copy(m_buffer.begin() + m_pos, m_buffer.begin() + m_pos + count, data);
|
|
+ m_pos += count;
|
|
+ return (count);
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+stream::size_type inputStreamStringAdapter::skip(const size_type count)
|
|
+{
|
|
+ if (m_pos + count >= m_end)
|
|
+ {
|
|
+ const size_type remaining = m_end - m_pos;
|
|
+ m_pos = m_end;
|
|
+ return (remaining);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ m_pos += count;
|
|
+ return (count);
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
diff --git a/src/utility/inputStreamStringProxyAdapter.cpp b/src/utility/inputStreamStringProxyAdapter.cpp
|
|
new file mode 100644
|
|
index 0000000..5e4b60b
|
|
--- /dev/null
|
|
+++ b/src/utility/inputStreamStringProxyAdapter.cpp
|
|
@@ -0,0 +1,89 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#include "vmime/utility/inputStreamStringProxyAdapter.hpp"
|
|
+#include "vmime/utility/stringProxy.hpp"
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+inputStreamStringProxyAdapter::inputStreamStringProxyAdapter(const stringProxy& buffer)
|
|
+ : m_buffer(buffer), m_pos(0)
|
|
+{
|
|
+}
|
|
+
|
|
+
|
|
+bool inputStreamStringProxyAdapter::eof() const
|
|
+{
|
|
+ return (m_pos >= m_buffer.length());
|
|
+}
|
|
+
|
|
+
|
|
+void inputStreamStringProxyAdapter::reset()
|
|
+{
|
|
+ m_pos = 0;
|
|
+}
|
|
+
|
|
+
|
|
+stream::size_type inputStreamStringProxyAdapter::read
|
|
+ (value_type* const data, const size_type count)
|
|
+{
|
|
+ const size_type remaining = m_buffer.length() - m_pos;
|
|
+
|
|
+ if (count > remaining)
|
|
+ {
|
|
+ std::copy(m_buffer.it_begin() + m_pos, m_buffer.it_end(), data);
|
|
+ m_pos = m_buffer.length();
|
|
+ return (remaining);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ std::copy(m_buffer.it_begin() + m_pos, m_buffer.it_begin() + m_pos + count, data);
|
|
+ m_pos += count;
|
|
+ return (count);
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+stream::size_type inputStreamStringProxyAdapter::skip(const size_type count)
|
|
+{
|
|
+ const size_type remaining = m_buffer.length() - m_pos;
|
|
+
|
|
+ if (count > remaining)
|
|
+ {
|
|
+ m_pos = m_buffer.length();
|
|
+ return (remaining);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ m_pos += count;
|
|
+ return (count);
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
diff --git a/src/utility/outputStream.cpp b/src/utility/outputStream.cpp
|
|
new file mode 100644
|
|
index 0000000..8a65db5
|
|
--- /dev/null
|
|
+++ b/src/utility/outputStream.cpp
|
|
@@ -0,0 +1,33 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#include "vmime/utility/outputStream.hpp"
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
diff --git a/src/utility/outputStreamAdapter.cpp b/src/utility/outputStreamAdapter.cpp
|
|
new file mode 100644
|
|
index 0000000..2da94f1
|
|
--- /dev/null
|
|
+++ b/src/utility/outputStreamAdapter.cpp
|
|
@@ -0,0 +1,54 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#include "vmime/utility/outputStreamAdapter.hpp"
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+outputStreamAdapter::outputStreamAdapter(std::ostream& os)
|
|
+ : m_stream(os)
|
|
+{
|
|
+}
|
|
+
|
|
+
|
|
+void outputStreamAdapter::write
|
|
+ (const value_type* const data, const size_type count)
|
|
+{
|
|
+ m_stream.exceptions(std::ios_base::badbit);
|
|
+ m_stream.write(data, count);
|
|
+}
|
|
+
|
|
+
|
|
+void outputStreamAdapter::flush()
|
|
+{
|
|
+ m_stream.exceptions(std::ios_base::badbit);
|
|
+ m_stream.flush();
|
|
+}
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
diff --git a/src/utility/outputStreamByteArrayAdapter.cpp b/src/utility/outputStreamByteArrayAdapter.cpp
|
|
new file mode 100644
|
|
index 0000000..97b27d2
|
|
--- /dev/null
|
|
+++ b/src/utility/outputStreamByteArrayAdapter.cpp
|
|
@@ -0,0 +1,51 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#include "vmime/utility/outputStreamByteArrayAdapter.hpp"
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+outputStreamByteArrayAdapter::outputStreamByteArrayAdapter(byteArray& array)
|
|
+ : m_array(array)
|
|
+{
|
|
+}
|
|
+
|
|
+
|
|
+void outputStreamByteArrayAdapter::write(const value_type* const data, const size_type count)
|
|
+{
|
|
+ m_array.insert(m_array.end(), data, data + count);
|
|
+}
|
|
+
|
|
+
|
|
+void outputStreamByteArrayAdapter::flush()
|
|
+{
|
|
+ // Do nothing
|
|
+}
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
diff --git a/src/utility/outputStreamSocketAdapter.cpp b/src/utility/outputStreamSocketAdapter.cpp
|
|
new file mode 100644
|
|
index 0000000..d933e73
|
|
--- /dev/null
|
|
+++ b/src/utility/outputStreamSocketAdapter.cpp
|
|
@@ -0,0 +1,68 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#include "vmime/utility/outputStreamSocketAdapter.hpp"
|
|
+
|
|
+
|
|
+#if VMIME_HAVE_MESSAGING_FEATURES
|
|
+
|
|
+
|
|
+#include "vmime/net/socket.hpp"
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+outputStreamSocketAdapter::outputStreamSocketAdapter(net::socket& sok)
|
|
+ : m_socket(sok)
|
|
+{
|
|
+}
|
|
+
|
|
+
|
|
+void outputStreamSocketAdapter::write
|
|
+ (const value_type* const data, const size_type count)
|
|
+{
|
|
+ m_socket.sendRaw(data, count);
|
|
+}
|
|
+
|
|
+
|
|
+void outputStreamSocketAdapter::flush()
|
|
+{
|
|
+ // Do nothing
|
|
+}
|
|
+
|
|
+
|
|
+stream::size_type outputStreamSocketAdapter::getBlockSize()
|
|
+{
|
|
+ return m_socket.getBlockSize();
|
|
+}
|
|
+
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
+
|
|
+#endif // VMIME_HAVE_MESSAGING_FEATURES
|
|
+
|
|
diff --git a/src/utility/outputStreamStringAdapter.cpp b/src/utility/outputStreamStringAdapter.cpp
|
|
new file mode 100644
|
|
index 0000000..62b2a72
|
|
--- /dev/null
|
|
+++ b/src/utility/outputStreamStringAdapter.cpp
|
|
@@ -0,0 +1,51 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#include "vmime/utility/outputStreamStringAdapter.hpp"
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+outputStreamStringAdapter::outputStreamStringAdapter(string& buffer)
|
|
+ : m_buffer(buffer)
|
|
+{
|
|
+}
|
|
+
|
|
+
|
|
+void outputStreamStringAdapter::write(const value_type* const data, const size_type count)
|
|
+{
|
|
+ m_buffer.append(data, count);
|
|
+}
|
|
+
|
|
+
|
|
+void outputStreamStringAdapter::flush()
|
|
+{
|
|
+ // Do nothing
|
|
+}
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
diff --git a/src/utility/stream.cpp b/src/utility/stream.cpp
|
|
index ec30b7d..1c940c2 100644
|
|
--- a/src/utility/stream.cpp
|
|
+++ b/src/utility/stream.cpp
|
|
@@ -22,503 +22,18 @@
|
|
//
|
|
|
|
#include "vmime/utility/stream.hpp"
|
|
-#include "vmime/utility/stringProxy.hpp"
|
|
|
|
-#include <algorithm> // for std::copy
|
|
-#include <iterator> // for std::back_inserter
|
|
-
|
|
-#if VMIME_HAVE_MESSAGING_FEATURES
|
|
- #include "vmime/net/socket.hpp"
|
|
-#endif
|
|
|
|
|
|
namespace vmime {
|
|
namespace utility {
|
|
|
|
|
|
-// stream
|
|
-
|
|
stream::size_type stream::getBlockSize()
|
|
{
|
|
return 32768; // 32 KB
|
|
}
|
|
|
|
|
|
-// Helpers
|
|
-
|
|
-outputStream& operator<<(outputStream& os, const stream::value_type c)
|
|
-{
|
|
- os.write(&c, 1);
|
|
- return (os);
|
|
-}
|
|
-
|
|
-
|
|
-outputStream& operator<<(outputStream& os, const string& str)
|
|
-{
|
|
- os.write(str.data(), str.length());
|
|
- return (os);
|
|
-}
|
|
-
|
|
-
|
|
-stream::size_type bufferedStreamCopy(inputStream& is, outputStream& os)
|
|
-{
|
|
- return bufferedStreamCopy(is, os, 0, NULL);
|
|
-}
|
|
-
|
|
-
|
|
-stream::size_type bufferedStreamCopy(inputStream& is, outputStream& os,
|
|
- const stream::size_type length, progressListener* progress)
|
|
-{
|
|
- const stream::size_type blockSize =
|
|
- std::min(is.getBlockSize(), os.getBlockSize());
|
|
-
|
|
- std::vector <stream::value_type> vbuffer(blockSize);
|
|
-
|
|
- stream::value_type* buffer = &vbuffer.front();
|
|
- stream::size_type total = 0;
|
|
-
|
|
- if (progress != NULL)
|
|
- progress->start(length);
|
|
-
|
|
- while (!is.eof())
|
|
- {
|
|
- const stream::size_type read = is.read(buffer, blockSize);
|
|
-
|
|
- if (read != 0)
|
|
- {
|
|
- os.write(buffer, read);
|
|
- total += read;
|
|
-
|
|
- if (progress != NULL)
|
|
- progress->progress(total, std::max(total, length));
|
|
- }
|
|
- }
|
|
-
|
|
- if (progress != NULL)
|
|
- progress->stop(total);
|
|
-
|
|
- return (total);
|
|
-}
|
|
-
|
|
-
|
|
-
|
|
-// outputStreamAdapter
|
|
-
|
|
-outputStreamAdapter::outputStreamAdapter(std::ostream& os)
|
|
- : m_stream(os)
|
|
-{
|
|
-}
|
|
-
|
|
-
|
|
-void outputStreamAdapter::write
|
|
- (const value_type* const data, const size_type count)
|
|
-{
|
|
- m_stream.exceptions(std::ios_base::badbit);
|
|
- m_stream.write(data, count);
|
|
-}
|
|
-
|
|
-
|
|
-void outputStreamAdapter::flush()
|
|
-{
|
|
- m_stream.exceptions(std::ios_base::badbit);
|
|
- m_stream.flush();
|
|
-}
|
|
-
|
|
-
|
|
-
|
|
-// outputStreamStringAdapter
|
|
-
|
|
-outputStreamStringAdapter::outputStreamStringAdapter(string& buffer)
|
|
- : m_buffer(buffer)
|
|
-{
|
|
-}
|
|
-
|
|
-
|
|
-void outputStreamStringAdapter::write(const value_type* const data, const size_type count)
|
|
-{
|
|
- m_buffer.append(data, count);
|
|
-}
|
|
-
|
|
-
|
|
-void outputStreamStringAdapter::flush()
|
|
-{
|
|
- // Do nothing
|
|
-}
|
|
-
|
|
-
|
|
-
|
|
-// outputStreamByteArrayAdapter
|
|
-
|
|
-outputStreamByteArrayAdapter::outputStreamByteArrayAdapter(byteArray& array)
|
|
- : m_array(array)
|
|
-{
|
|
-}
|
|
-
|
|
-
|
|
-void outputStreamByteArrayAdapter::write(const value_type* const data, const size_type count)
|
|
-{
|
|
- m_array.insert(m_array.end(), data, data + count);
|
|
-}
|
|
-
|
|
-
|
|
-void outputStreamByteArrayAdapter::flush()
|
|
-{
|
|
- // Do nothing
|
|
-}
|
|
-
|
|
-
|
|
-
|
|
-// inputStreamAdapter
|
|
-
|
|
-inputStreamAdapter::inputStreamAdapter(std::istream& is)
|
|
- : m_stream(is)
|
|
-{
|
|
-}
|
|
-
|
|
-
|
|
-bool inputStreamAdapter::eof() const
|
|
-{
|
|
- return (m_stream.eof());
|
|
-}
|
|
-
|
|
-
|
|
-void inputStreamAdapter::reset()
|
|
-{
|
|
- m_stream.exceptions(std::ios_base::badbit);
|
|
- m_stream.seekg(0, std::ios::beg);
|
|
- m_stream.clear();
|
|
-}
|
|
-
|
|
-
|
|
-stream::size_type inputStreamAdapter::read
|
|
- (value_type* const data, const size_type count)
|
|
-{
|
|
- m_stream.exceptions(std::ios_base::badbit);
|
|
- m_stream.read(data, count);
|
|
- return (m_stream.gcount());
|
|
-}
|
|
-
|
|
-
|
|
-stream::size_type inputStreamAdapter::skip(const size_type count)
|
|
-{
|
|
- m_stream.exceptions(std::ios_base::badbit);
|
|
- m_stream.ignore(count);
|
|
- return (m_stream.gcount());
|
|
-}
|
|
-
|
|
-
|
|
-
|
|
-// inputStreamStringAdapter
|
|
-
|
|
-inputStreamStringAdapter::inputStreamStringAdapter(const string& buffer)
|
|
- : m_buffer(buffer), m_begin(0), m_end(buffer.length()), m_pos(0)
|
|
-{
|
|
-}
|
|
-
|
|
-
|
|
-inputStreamStringAdapter::inputStreamStringAdapter(const string& buffer,
|
|
- const string::size_type begin, const string::size_type end)
|
|
- : m_buffer(buffer), m_begin(begin), m_end(end), m_pos(begin)
|
|
-{
|
|
-}
|
|
-
|
|
-
|
|
-bool inputStreamStringAdapter::eof() const
|
|
-{
|
|
- return (m_pos >= m_end);
|
|
-}
|
|
-
|
|
-
|
|
-void inputStreamStringAdapter::reset()
|
|
-{
|
|
- m_pos = m_begin;
|
|
-}
|
|
-
|
|
-
|
|
-stream::size_type inputStreamStringAdapter::read
|
|
- (value_type* const data, const size_type count)
|
|
-{
|
|
- if (m_pos + count >= m_end)
|
|
- {
|
|
- const size_type remaining = m_end - m_pos;
|
|
-
|
|
- std::copy(m_buffer.begin() + m_pos, m_buffer.end(), data);
|
|
- m_pos = m_end;
|
|
- return (remaining);
|
|
- }
|
|
- else
|
|
- {
|
|
- std::copy(m_buffer.begin() + m_pos, m_buffer.begin() + m_pos + count, data);
|
|
- m_pos += count;
|
|
- return (count);
|
|
- }
|
|
-}
|
|
-
|
|
-
|
|
-stream::size_type inputStreamStringAdapter::skip(const size_type count)
|
|
-{
|
|
- if (m_pos + count >= m_end)
|
|
- {
|
|
- const size_type remaining = m_end - m_pos;
|
|
- m_pos = m_end;
|
|
- return (remaining);
|
|
- }
|
|
- else
|
|
- {
|
|
- m_pos += count;
|
|
- return (count);
|
|
- }
|
|
-}
|
|
-
|
|
-
|
|
-
|
|
-// inputStreamStringProxyAdapter
|
|
-
|
|
-inputStreamStringProxyAdapter::inputStreamStringProxyAdapter(const stringProxy& buffer)
|
|
- : m_buffer(buffer), m_pos(0)
|
|
-{
|
|
-}
|
|
-
|
|
-
|
|
-bool inputStreamStringProxyAdapter::eof() const
|
|
-{
|
|
- return (m_pos >= m_buffer.length());
|
|
-}
|
|
-
|
|
-
|
|
-void inputStreamStringProxyAdapter::reset()
|
|
-{
|
|
- m_pos = 0;
|
|
-}
|
|
-
|
|
-
|
|
-stream::size_type inputStreamStringProxyAdapter::read
|
|
- (value_type* const data, const size_type count)
|
|
-{
|
|
- const size_type remaining = m_buffer.length() - m_pos;
|
|
-
|
|
- if (count > remaining)
|
|
- {
|
|
- std::copy(m_buffer.it_begin() + m_pos, m_buffer.it_end(), data);
|
|
- m_pos = m_buffer.length();
|
|
- return (remaining);
|
|
- }
|
|
- else
|
|
- {
|
|
- std::copy(m_buffer.it_begin() + m_pos, m_buffer.it_begin() + m_pos + count, data);
|
|
- m_pos += count;
|
|
- return (count);
|
|
- }
|
|
-}
|
|
-
|
|
-
|
|
-stream::size_type inputStreamStringProxyAdapter::skip(const size_type count)
|
|
-{
|
|
- const size_type remaining = m_buffer.length() - m_pos;
|
|
-
|
|
- if (count > remaining)
|
|
- {
|
|
- m_pos = m_buffer.length();
|
|
- return (remaining);
|
|
- }
|
|
- else
|
|
- {
|
|
- m_pos += count;
|
|
- return (count);
|
|
- }
|
|
-}
|
|
-
|
|
-
|
|
-
|
|
-// inputStreamPointerAdapter
|
|
-
|
|
-inputStreamPointerAdapter::inputStreamPointerAdapter(std::istream* is, const bool own)
|
|
- : m_stream(is), m_own(own)
|
|
-{
|
|
-}
|
|
-
|
|
-
|
|
-inputStreamPointerAdapter::inputStreamPointerAdapter(const inputStreamPointerAdapter&)
|
|
- : inputStream(), m_stream(NULL), m_own(false)
|
|
-{
|
|
- // Not copiable
|
|
-}
|
|
-
|
|
-
|
|
-inputStreamPointerAdapter::~inputStreamPointerAdapter()
|
|
-{
|
|
- if (m_own)
|
|
- delete (m_stream);
|
|
-}
|
|
-
|
|
-
|
|
-bool inputStreamPointerAdapter::eof() const
|
|
-{
|
|
- return (m_stream->eof());
|
|
-}
|
|
-
|
|
-
|
|
-void inputStreamPointerAdapter::reset()
|
|
-{
|
|
- m_stream->exceptions(std::ios_base::badbit);
|
|
- m_stream->seekg(0, std::ios::beg);
|
|
- m_stream->clear();
|
|
-}
|
|
-
|
|
-
|
|
-stream::size_type inputStreamPointerAdapter::read
|
|
- (value_type* const data, const size_type count)
|
|
-{
|
|
- m_stream->exceptions(std::ios_base::badbit);
|
|
- m_stream->read(data, count);
|
|
- return (m_stream->gcount());
|
|
-}
|
|
-
|
|
-
|
|
-stream::size_type inputStreamPointerAdapter::skip(const size_type count)
|
|
-{
|
|
- m_stream->exceptions(std::ios_base::badbit);
|
|
- m_stream->ignore(count);
|
|
- return (m_stream->gcount());
|
|
-}
|
|
-
|
|
-
|
|
-
|
|
-// inputStreamByteBufferAdapter
|
|
-
|
|
-inputStreamByteBufferAdapter::inputStreamByteBufferAdapter(const byte_t* buffer, const size_type length)
|
|
- : m_buffer(buffer), m_length(length), m_pos(0)
|
|
-{
|
|
-}
|
|
-
|
|
-
|
|
-bool inputStreamByteBufferAdapter::eof() const
|
|
-{
|
|
- return m_pos >= m_length;
|
|
-}
|
|
-
|
|
-
|
|
-void inputStreamByteBufferAdapter::reset()
|
|
-{
|
|
- m_pos = 0;
|
|
-}
|
|
-
|
|
-
|
|
-stream::size_type inputStreamByteBufferAdapter::read
|
|
- (value_type* const data, const size_type count)
|
|
-{
|
|
- const size_type remaining = m_length - m_pos;
|
|
-
|
|
- if (remaining < count)
|
|
- {
|
|
- std::copy(m_buffer + m_pos, m_buffer + m_pos + remaining, data);
|
|
- m_pos += remaining;
|
|
-
|
|
- return remaining;
|
|
- }
|
|
- else
|
|
- {
|
|
- std::copy(m_buffer + m_pos, m_buffer + m_pos + count, data);
|
|
- m_pos += count;
|
|
-
|
|
- return count;
|
|
- }
|
|
-}
|
|
-
|
|
-
|
|
-stream::size_type inputStreamByteBufferAdapter::skip(const size_type count)
|
|
-{
|
|
- const size_type remaining = m_length - m_pos;
|
|
-
|
|
- if (remaining < count)
|
|
- {
|
|
- m_pos += remaining;
|
|
- return remaining;
|
|
- }
|
|
- else
|
|
- {
|
|
- m_pos += count;
|
|
- return count;
|
|
- }
|
|
-}
|
|
-
|
|
-
|
|
-
|
|
-#ifdef VMIME_HAVE_MESSAGING_FEATURES
|
|
-
|
|
-
|
|
-// outputStreamSocketAdapter
|
|
-
|
|
-outputStreamSocketAdapter::outputStreamSocketAdapter(net::socket& sok)
|
|
- : m_socket(sok)
|
|
-{
|
|
-}
|
|
-
|
|
-
|
|
-void outputStreamSocketAdapter::write
|
|
- (const value_type* const data, const size_type count)
|
|
-{
|
|
- m_socket.sendRaw(data, count);
|
|
-}
|
|
-
|
|
-
|
|
-void outputStreamSocketAdapter::flush()
|
|
-{
|
|
- // Do nothing
|
|
-}
|
|
-
|
|
-
|
|
-stream::size_type outputStreamSocketAdapter::getBlockSize()
|
|
-{
|
|
- return m_socket.getBlockSize();
|
|
-}
|
|
-
|
|
-
|
|
-
|
|
-// inputStreamSocketAdapter
|
|
-
|
|
-inputStreamSocketAdapter::inputStreamSocketAdapter(net::socket& sok)
|
|
- : m_socket(sok)
|
|
-{
|
|
-}
|
|
-
|
|
-
|
|
-bool inputStreamSocketAdapter::eof() const
|
|
-{
|
|
- // Can't know...
|
|
- return false;
|
|
-}
|
|
-
|
|
-
|
|
-void inputStreamSocketAdapter::reset()
|
|
-{
|
|
- // Not supported
|
|
-}
|
|
-
|
|
-
|
|
-stream::size_type inputStreamSocketAdapter::read
|
|
- (value_type* const data, const size_type count)
|
|
-{
|
|
- return m_socket.receiveRaw(data, count);
|
|
-}
|
|
-
|
|
-
|
|
-stream::size_type inputStreamSocketAdapter::skip
|
|
- (const size_type /* count */)
|
|
-{
|
|
- // Not supported
|
|
- return 0;
|
|
-}
|
|
-
|
|
-
|
|
-stream::size_type inputStreamSocketAdapter::getBlockSize()
|
|
-{
|
|
- return m_socket.getBlockSize();
|
|
-}
|
|
-
|
|
-
|
|
-#endif // VMIME_HAVE_MESSAGING_FEATURES
|
|
-
|
|
-
|
|
} // utility
|
|
} // vmime
|
|
diff --git a/src/utility/streamUtils.cpp b/src/utility/streamUtils.cpp
|
|
new file mode 100644
|
|
index 0000000..f1d3b9d
|
|
--- /dev/null
|
|
+++ b/src/utility/streamUtils.cpp
|
|
@@ -0,0 +1,92 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#include "vmime/utility/streamUtils.hpp"
|
|
+
|
|
+#include <algorithm> // for std::copy
|
|
+#include <iterator> // for std::back_inserter
|
|
+
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+outputStream& operator<<(outputStream& os, const stream::value_type c)
|
|
+{
|
|
+ os.write(&c, 1);
|
|
+ return (os);
|
|
+}
|
|
+
|
|
+
|
|
+outputStream& operator<<(outputStream& os, const string& str)
|
|
+{
|
|
+ os.write(str.data(), str.length());
|
|
+ return (os);
|
|
+}
|
|
+
|
|
+
|
|
+stream::size_type bufferedStreamCopy(inputStream& is, outputStream& os)
|
|
+{
|
|
+ return bufferedStreamCopy(is, os, 0, NULL);
|
|
+}
|
|
+
|
|
+
|
|
+stream::size_type bufferedStreamCopy(inputStream& is, outputStream& os,
|
|
+ const stream::size_type length, progressListener* progress)
|
|
+{
|
|
+ const stream::size_type blockSize =
|
|
+ std::min(is.getBlockSize(), os.getBlockSize());
|
|
+
|
|
+ std::vector <stream::value_type> vbuffer(blockSize);
|
|
+
|
|
+ stream::value_type* buffer = &vbuffer.front();
|
|
+ stream::size_type total = 0;
|
|
+
|
|
+ if (progress != NULL)
|
|
+ progress->start(length);
|
|
+
|
|
+ while (!is.eof())
|
|
+ {
|
|
+ const stream::size_type read = is.read(buffer, blockSize);
|
|
+
|
|
+ if (read != 0)
|
|
+ {
|
|
+ os.write(buffer, read);
|
|
+ total += read;
|
|
+
|
|
+ if (progress != NULL)
|
|
+ progress->progress(total, std::max(total, length));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (progress != NULL)
|
|
+ progress->stop(total);
|
|
+
|
|
+ return (total);
|
|
+}
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
diff --git a/src/utility/stringProxy.cpp b/src/utility/stringProxy.cpp
|
|
index a4ba6d2..74344b5 100644
|
|
--- a/src/utility/stringProxy.cpp
|
|
+++ b/src/utility/stringProxy.cpp
|
|
@@ -23,6 +23,8 @@
|
|
|
|
#include "vmime/utility/stringProxy.hpp"
|
|
|
|
+#include "vmime/utility/outputStreamAdapter.hpp"
|
|
+
|
|
#include <iterator>
|
|
#include <algorithm>
|
|
|
|
diff --git a/src/word.cpp b/src/word.cpp
|
|
index aeaa737..79060a1 100644
|
|
--- a/src/word.cpp
|
|
+++ b/src/word.cpp
|
|
@@ -28,6 +28,9 @@
|
|
#include "vmime/utility/smartPtr.hpp"
|
|
#include "vmime/parserHelpers.hpp"
|
|
|
|
+#include "vmime/utility/outputStreamStringAdapter.hpp"
|
|
+#include "vmime/utility/inputStreamStringAdapter.hpp"
|
|
+
|
|
#include "vmime/utility/encoder/encoder.hpp"
|
|
#include "vmime/utility/encoder/b64Encoder.hpp"
|
|
#include "vmime/utility/encoder/qpEncoder.hpp"
|
|
diff --git a/src/wordEncoder.cpp b/src/wordEncoder.cpp
|
|
index 67bd7a1..194a189 100644
|
|
--- a/src/wordEncoder.cpp
|
|
+++ b/src/wordEncoder.cpp
|
|
@@ -33,6 +33,9 @@
|
|
|
|
#include "vmime/utility/stringUtils.hpp"
|
|
|
|
+#include "vmime/utility/outputStreamStringAdapter.hpp"
|
|
+#include "vmime/utility/inputStreamStringAdapter.hpp"
|
|
+
|
|
|
|
namespace vmime
|
|
{
|
|
diff --git a/vmime/base.hpp b/vmime/base.hpp
|
|
index 60e637d..b794031 100644
|
|
--- a/vmime/base.hpp
|
|
+++ b/vmime/base.hpp
|
|
@@ -35,7 +35,6 @@
|
|
#include "vmime/config.hpp"
|
|
#include "vmime/types.hpp"
|
|
#include "vmime/constants.hpp"
|
|
-#include "vmime/utility/stream.hpp"
|
|
#include "vmime/utility/smartPtr.hpp"
|
|
|
|
|
|
@@ -255,7 +254,26 @@ namespace vmime
|
|
return y.dynamicCast <X>();
|
|
}
|
|
|
|
+ /** Inherit from this class to indicate the subclass is not copyable,
|
|
+ * ie. you want to prohibit copy construction and copy assignment.
|
|
+ */
|
|
+ class noncopyable
|
|
+ {
|
|
+ protected:
|
|
+
|
|
+ noncopyable() { }
|
|
+ virtual ~noncopyable() { }
|
|
+
|
|
+ private:
|
|
+
|
|
+ noncopyable(const noncopyable&);
|
|
+ void operator=(const noncopyable&);
|
|
+ };
|
|
+
|
|
} // vmime
|
|
|
|
|
|
+#include "vmime/utility/stream.hpp"
|
|
+
|
|
+
|
|
#endif // VMIME_BASE_HPP_INCLUDED
|
|
diff --git a/vmime/charset.hpp b/vmime/charset.hpp
|
|
index b2e241c..5f5e8e5 100644
|
|
--- a/vmime/charset.hpp
|
|
+++ b/vmime/charset.hpp
|
|
@@ -26,6 +26,8 @@
|
|
|
|
|
|
#include "vmime/base.hpp"
|
|
+#include "vmime/utility/inputStream.hpp"
|
|
+#include "vmime/utility/outputStream.hpp"
|
|
#include "vmime/component.hpp"
|
|
|
|
|
|
diff --git a/vmime/component.hpp b/vmime/component.hpp
|
|
index b38127f..12b0406 100644
|
|
--- a/vmime/component.hpp
|
|
+++ b/vmime/component.hpp
|
|
@@ -26,6 +26,8 @@
|
|
|
|
|
|
#include "vmime/base.hpp"
|
|
+#include "vmime/utility/inputStream.hpp"
|
|
+#include "vmime/utility/outputStream.hpp"
|
|
|
|
|
|
namespace vmime
|
|
diff --git a/vmime/net/imap/IMAPParser.hpp b/vmime/net/imap/IMAPParser.hpp
|
|
index d71c3ca..f430510 100644
|
|
--- a/vmime/net/imap/IMAPParser.hpp
|
|
+++ b/vmime/net/imap/IMAPParser.hpp
|
|
@@ -37,6 +37,9 @@
|
|
#include "vmime/utility/encoder/b64Encoder.hpp"
|
|
#include "vmime/utility/encoder/qpEncoder.hpp"
|
|
|
|
+#include "vmime/utility/inputStreamStringAdapter.hpp"
|
|
+#include "vmime/utility/outputStreamStringAdapter.hpp"
|
|
+
|
|
#include "vmime/platform.hpp"
|
|
|
|
#include "vmime/net/timeoutHandler.hpp"
|
|
@@ -3825,7 +3828,7 @@ public:
|
|
: m_date_time(NULL), m_number(NULL), m_envelope(NULL),
|
|
m_uniqueid(NULL), m_nstring(NULL), m_body(NULL), m_flag_list(NULL),
|
|
m_section(NULL)
|
|
-
|
|
+
|
|
{
|
|
}
|
|
|
|
diff --git a/vmime/utility/filteredStream.hpp b/vmime/utility/filteredStream.hpp
|
|
index 00be785..2a55edd 100644
|
|
--- a/vmime/utility/filteredStream.hpp
|
|
+++ b/vmime/utility/filteredStream.hpp
|
|
@@ -27,7 +27,8 @@
|
|
|
|
#include <algorithm>
|
|
|
|
-#include "vmime/utility/stream.hpp"
|
|
+#include "vmime/utility/inputStream.hpp"
|
|
+#include "vmime/utility/outputStream.hpp"
|
|
|
|
|
|
namespace vmime {
|
|
diff --git a/vmime/utility/inputStream.hpp b/vmime/utility/inputStream.hpp
|
|
new file mode 100644
|
|
index 0000000..4a76a7d
|
|
--- /dev/null
|
|
+++ b/vmime/utility/inputStream.hpp
|
|
@@ -0,0 +1,76 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#ifndef VMIME_UTILITY_INPUTSTREAM_HPP_INCLUDED
|
|
+#define VMIME_UTILITY_INPUTSTREAM_HPP_INCLUDED
|
|
+
|
|
+
|
|
+#include "vmime/utility/stream.hpp"
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+/** Simple input stream.
|
|
+ */
|
|
+
|
|
+class inputStream : public stream
|
|
+{
|
|
+public:
|
|
+
|
|
+ /** Test for end of stream (no more data to read).
|
|
+ *
|
|
+ * @return true if we have reached the end of stream, false otherwise
|
|
+ */
|
|
+ virtual bool eof() const = 0;
|
|
+
|
|
+ /** Set the read pointer to the beginning of the stream.
|
|
+ *
|
|
+ * @warning WARNING: this may not work for all stream types.
|
|
+ */
|
|
+ virtual void reset() = 0;
|
|
+
|
|
+ /** Read data from the stream.
|
|
+ *
|
|
+ * @param data will receive the data read
|
|
+ * @param count maximum number of bytes to read
|
|
+ * @return number of bytes read
|
|
+ */
|
|
+ virtual size_type read(value_type* const data, const size_type count) = 0;
|
|
+
|
|
+ /** Skip a number of bytes.
|
|
+ *
|
|
+ * @param count maximum number of bytes to ignore
|
|
+ * @return number of bytes skipped
|
|
+ */
|
|
+ virtual size_type skip(const size_type count) = 0;
|
|
+};
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
+
|
|
+#endif // VMIME_UTILITY_INPUTSTREAM_HPP_INCLUDED
|
|
+
|
|
diff --git a/vmime/utility/inputStreamAdapter.hpp b/vmime/utility/inputStreamAdapter.hpp
|
|
new file mode 100644
|
|
index 0000000..278ab52
|
|
--- /dev/null
|
|
+++ b/vmime/utility/inputStreamAdapter.hpp
|
|
@@ -0,0 +1,64 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#ifndef VMIME_UTILITY_INPUTSTREAMADAPTER_HPP_INCLUDED
|
|
+#define VMIME_UTILITY_INPUTSTREAMADAPTER_HPP_INCLUDED
|
|
+
|
|
+
|
|
+#include "vmime/utility/inputStream.hpp"
|
|
+
|
|
+#include <istream>
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+/** An adapter class for C++ standard input streams.
|
|
+ */
|
|
+
|
|
+class inputStreamAdapter : public inputStream
|
|
+{
|
|
+public:
|
|
+
|
|
+ /** @param is input stream to wrap
|
|
+ */
|
|
+ inputStreamAdapter(std::istream& is);
|
|
+
|
|
+ bool eof() const;
|
|
+ void reset();
|
|
+ size_type read(value_type* const data, const size_type count);
|
|
+ size_type skip(const size_type count);
|
|
+
|
|
+private:
|
|
+
|
|
+ std::istream& m_stream;
|
|
+};
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
+
|
|
+#endif // VMIME_UTILITY_INPUTSTREAMADAPTER_HPP_INCLUDED
|
|
+
|
|
diff --git a/vmime/utility/inputStreamByteBufferAdapter.hpp b/vmime/utility/inputStreamByteBufferAdapter.hpp
|
|
new file mode 100644
|
|
index 0000000..0f6a442
|
|
--- /dev/null
|
|
+++ b/vmime/utility/inputStreamByteBufferAdapter.hpp
|
|
@@ -0,0 +1,63 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#ifndef VMIME_UTILITY_INPUTSTREAMBYTEBUFFERADAPTER_HPP_INCLUDED
|
|
+#define VMIME_UTILITY_INPUTSTREAMBYTEBUFFERADAPTER_HPP_INCLUDED
|
|
+
|
|
+
|
|
+#include "vmime/utility/inputStream.hpp"
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+/** An adapter class for reading from an array of bytes.
|
|
+ */
|
|
+
|
|
+class inputStreamByteBufferAdapter : public inputStream
|
|
+{
|
|
+public:
|
|
+
|
|
+ inputStreamByteBufferAdapter(const byte_t* buffer, size_type length);
|
|
+
|
|
+ bool eof() const;
|
|
+ void reset();
|
|
+ size_type read(value_type* const data, const size_type count);
|
|
+ size_type skip(const size_type count);
|
|
+
|
|
+private:
|
|
+
|
|
+ const byte_t* m_buffer;
|
|
+ const size_type m_length;
|
|
+
|
|
+ size_type m_pos;
|
|
+};
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
+
|
|
+#endif // VMIME_UTILITY_INPUTSTREAMBYTEBUFFERADAPTER_HPP_INCLUDED
|
|
+
|
|
diff --git a/vmime/utility/inputStreamPointerAdapter.hpp b/vmime/utility/inputStreamPointerAdapter.hpp
|
|
new file mode 100644
|
|
index 0000000..44e9bad
|
|
--- /dev/null
|
|
+++ b/vmime/utility/inputStreamPointerAdapter.hpp
|
|
@@ -0,0 +1,63 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#ifndef VMIME_UTILITY_INPUTSTREAMPOINTERADAPTER_HPP_INCLUDED
|
|
+#define VMIME_UTILITY_INPUTSTREAMPOINTERADAPTER_HPP_INCLUDED
|
|
+
|
|
+
|
|
+#include "vmime/utility/inputStreamAdapter.hpp"
|
|
+
|
|
+#include <istream>
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+/** An adapter class for pointer to C++ standard input stream.
|
|
+ */
|
|
+
|
|
+class inputStreamPointerAdapter : public inputStreamAdapter
|
|
+{
|
|
+public:
|
|
+
|
|
+ /** @param is input stream to wrap
|
|
+ * @param own if set to 'true', the pointer will be deleted when
|
|
+ * this object is destroyed
|
|
+ */
|
|
+ inputStreamPointerAdapter(std::istream* is, const bool own = true);
|
|
+ ~inputStreamPointerAdapter();
|
|
+
|
|
+private:
|
|
+
|
|
+ std::istream* m_stream;
|
|
+ const bool m_own;
|
|
+};
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
+
|
|
+#endif // VMIME_UTILITY_INPUTSTREAMPOINTERADAPTER_HPP_INCLUDED
|
|
+
|
|
diff --git a/vmime/utility/inputStreamSocketAdapter.hpp b/vmime/utility/inputStreamSocketAdapter.hpp
|
|
new file mode 100644
|
|
index 0000000..0f99c21
|
|
--- /dev/null
|
|
+++ b/vmime/utility/inputStreamSocketAdapter.hpp
|
|
@@ -0,0 +1,77 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#ifndef VMIME_UTILITY_INPUTSTREAMSOCKETADAPTER_HPP_INCLUDED
|
|
+#define VMIME_UTILITY_INPUTSTREAMSOCKETADAPTER_HPP_INCLUDED
|
|
+
|
|
+
|
|
+#include "vmime/utility/inputStream.hpp"
|
|
+
|
|
+
|
|
+#if VMIME_HAVE_MESSAGING_FEATURES
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace net {
|
|
+ class socket; // forward reference
|
|
+} // net
|
|
+} // vmime
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+/** An input stream that is connected to a socket.
|
|
+ */
|
|
+
|
|
+class inputStreamSocketAdapter : public inputStream
|
|
+{
|
|
+public:
|
|
+
|
|
+ inputStreamSocketAdapter(net::socket& sok);
|
|
+
|
|
+ bool eof() const;
|
|
+ void reset();
|
|
+ size_type read(value_type* const data, const size_type count);
|
|
+ size_type skip(const size_type count);
|
|
+
|
|
+ size_type getBlockSize();
|
|
+
|
|
+private:
|
|
+
|
|
+ inputStreamSocketAdapter(const inputStreamSocketAdapter&);
|
|
+
|
|
+ net::socket& m_socket;
|
|
+};
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
+
|
|
+#endif // VMIME_HAVE_MESSAGING_FEATURES
|
|
+
|
|
+
|
|
+#endif // VMIME_UTILITY_INPUTSTREAMSOCKETADAPTER_HPP_INCLUDED
|
|
+
|
|
diff --git a/vmime/utility/inputStreamStringAdapter.hpp b/vmime/utility/inputStreamStringAdapter.hpp
|
|
new file mode 100644
|
|
index 0000000..a7d986f
|
|
--- /dev/null
|
|
+++ b/vmime/utility/inputStreamStringAdapter.hpp
|
|
@@ -0,0 +1,66 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#ifndef VMIME_UTILITY_INPUTSTREAMSTRINGADAPTER_HPP_INCLUDED
|
|
+#define VMIME_UTILITY_INPUTSTREAMSTRINGADAPTER_HPP_INCLUDED
|
|
+
|
|
+
|
|
+#include "vmime/utility/inputStream.hpp"
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+/** An adapter class for string input.
|
|
+ */
|
|
+
|
|
+class inputStreamStringAdapter : public inputStream
|
|
+{
|
|
+public:
|
|
+
|
|
+ inputStreamStringAdapter(const string& buffer);
|
|
+ inputStreamStringAdapter(const string& buffer, const string::size_type begin, const string::size_type end);
|
|
+
|
|
+ bool eof() const;
|
|
+ void reset();
|
|
+ size_type read(value_type* const data, const size_type count);
|
|
+ size_type skip(const size_type count);
|
|
+
|
|
+private:
|
|
+
|
|
+ inputStreamStringAdapter(const inputStreamStringAdapter&);
|
|
+
|
|
+ const string m_buffer; // do _NOT_ keep a reference...
|
|
+ const string::size_type m_begin;
|
|
+ const string::size_type m_end;
|
|
+ string::size_type m_pos;
|
|
+};
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
+
|
|
+#endif // VMIME_UTILITY_INPUTSTREAMSTRINGADAPTER_HPP_INCLUDED
|
|
+
|
|
diff --git a/vmime/utility/inputStreamStringProxyAdapter.hpp b/vmime/utility/inputStreamStringProxyAdapter.hpp
|
|
new file mode 100644
|
|
index 0000000..74b3f60
|
|
--- /dev/null
|
|
+++ b/vmime/utility/inputStreamStringProxyAdapter.hpp
|
|
@@ -0,0 +1,68 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#ifndef VMIME_UTILITY_INPUTSTREAMSTRINGPROXYADAPTER_HPP_INCLUDED
|
|
+#define VMIME_UTILITY_INPUTSTREAMSTRINGPROXYADAPTER_HPP_INCLUDED
|
|
+
|
|
+
|
|
+#include "vmime/utility/inputStream.hpp"
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+class stringProxy;
|
|
+
|
|
+
|
|
+/** An adapter class for stringProxy input.
|
|
+ */
|
|
+
|
|
+class inputStreamStringProxyAdapter : public inputStream
|
|
+{
|
|
+public:
|
|
+
|
|
+ /** @param buffer stringProxy object to wrap
|
|
+ */
|
|
+ inputStreamStringProxyAdapter(const stringProxy& buffer);
|
|
+
|
|
+ bool eof() const;
|
|
+ void reset();
|
|
+ size_type read(value_type* const data, const size_type count);
|
|
+ size_type skip(const size_type count);
|
|
+
|
|
+private:
|
|
+
|
|
+ inputStreamStringProxyAdapter(const inputStreamStringProxyAdapter&);
|
|
+
|
|
+ const stringProxy& m_buffer;
|
|
+ string::size_type m_pos;
|
|
+};
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
+
|
|
+#endif // VMIME_UTILITY_INPUTSTREAMSTRINGPROXYADAPTER_HPP_INCLUDED
|
|
+
|
|
diff --git a/vmime/utility/outputStream.hpp b/vmime/utility/outputStream.hpp
|
|
new file mode 100644
|
|
index 0000000..7372d20
|
|
--- /dev/null
|
|
+++ b/vmime/utility/outputStream.hpp
|
|
@@ -0,0 +1,107 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#ifndef VMIME_UTILITY_OUTPUTSTREAM_HPP_INCLUDED
|
|
+#define VMIME_UTILITY_OUTPUTSTREAM_HPP_INCLUDED
|
|
+
|
|
+
|
|
+#include "vmime/utility/stream.hpp"
|
|
+
|
|
+
|
|
+#if defined(_MSC_VER) && (_MSC_VER <= 1200) // VC++6
|
|
+# include <cstring>
|
|
+#endif
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+/** Simple output stream.
|
|
+ */
|
|
+
|
|
+class outputStream : public stream
|
|
+{
|
|
+public:
|
|
+
|
|
+ /** Write data to the stream.
|
|
+ *
|
|
+ * @param data buffer containing data to write
|
|
+ * @param count number of bytes to write
|
|
+ */
|
|
+ virtual void write(const value_type* const data, const size_type count) = 0;
|
|
+
|
|
+ /** Flush this output stream and forces any buffered output
|
|
+ * bytes to be written out to the stream.
|
|
+ */
|
|
+ virtual void flush() = 0;
|
|
+};
|
|
+
|
|
+
|
|
+// Helpers functions
|
|
+
|
|
+outputStream& operator<<(outputStream& os, const string& str);
|
|
+outputStream& operator<<(outputStream& os, const stream::value_type c);
|
|
+
|
|
+
|
|
+#if defined(_MSC_VER) && (_MSC_VER <= 1200) // Internal compiler error with VC++6
|
|
+
|
|
+inline outputStream& operator<<(outputStream& os, const char* str)
|
|
+{
|
|
+ os.write(str, ::strlen(str));
|
|
+ return (os);
|
|
+}
|
|
+
|
|
+#else
|
|
+
|
|
+template <int N>
|
|
+outputStream& operator<<(outputStream& os, const char (&str)[N])
|
|
+{
|
|
+ os.write(str, N - 1);
|
|
+ return (os);
|
|
+}
|
|
+
|
|
+#endif // defined(_MSC_VER) && (_MSC_VER <= 1200)
|
|
+
|
|
+
|
|
+template <typename T>
|
|
+outputStream& operator<<(outputStream& os, const T& t)
|
|
+{
|
|
+ std::ostringstream oss;
|
|
+ oss.imbue(std::locale::classic()); // no formatting
|
|
+
|
|
+ oss << t;
|
|
+
|
|
+ os << oss.str();
|
|
+
|
|
+ return (os);
|
|
+}
|
|
+
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
+
|
|
+#endif // VMIME_UTILITY_OUTPUTSTREAM_HPP_INCLUDED
|
|
+
|
|
diff --git a/vmime/utility/outputStreamAdapter.hpp b/vmime/utility/outputStreamAdapter.hpp
|
|
new file mode 100644
|
|
index 0000000..be55d8d
|
|
--- /dev/null
|
|
+++ b/vmime/utility/outputStreamAdapter.hpp
|
|
@@ -0,0 +1,62 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#ifndef VMIME_UTILITY_OUTPUTSTREAMADAPTER_HPP_INCLUDED
|
|
+#define VMIME_UTILITY_OUTPUTSTREAMADAPTER_HPP_INCLUDED
|
|
+
|
|
+
|
|
+#include "vmime/utility/outputStream.hpp"
|
|
+
|
|
+#include <ostream>
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+/** An adapter class for C++ standard output streams.
|
|
+ */
|
|
+
|
|
+class outputStreamAdapter : public outputStream
|
|
+{
|
|
+public:
|
|
+
|
|
+ /** @param os output stream to wrap
|
|
+ */
|
|
+ outputStreamAdapter(std::ostream& os);
|
|
+
|
|
+ void write(const value_type* const data, const size_type count);
|
|
+ void flush();
|
|
+
|
|
+private:
|
|
+
|
|
+ std::ostream& m_stream;
|
|
+};
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
+
|
|
+#endif // VMIME_UTILITY_OUTPUTSTREAMADAPTER_HPP_INCLUDED
|
|
+
|
|
diff --git a/vmime/utility/outputStreamByteArrayAdapter.hpp b/vmime/utility/outputStreamByteArrayAdapter.hpp
|
|
new file mode 100644
|
|
index 0000000..bf7d839
|
|
--- /dev/null
|
|
+++ b/vmime/utility/outputStreamByteArrayAdapter.hpp
|
|
@@ -0,0 +1,58 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#ifndef VMIME_UTILITY_OUTPUTSTREAMBYTEARRAYADAPTER_HPP_INCLUDED
|
|
+#define VMIME_UTILITY_OUTPUTSTREAMBYTEARRAYADAPTER_HPP_INCLUDED
|
|
+
|
|
+
|
|
+#include "vmime/utility/outputStream.hpp"
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+/** An adapter class for byte array output.
|
|
+ */
|
|
+
|
|
+class outputStreamByteArrayAdapter : public outputStream
|
|
+{
|
|
+public:
|
|
+
|
|
+ outputStreamByteArrayAdapter(byteArray& array);
|
|
+
|
|
+ void write(const value_type* const data, const size_type count);
|
|
+ void flush();
|
|
+
|
|
+private:
|
|
+
|
|
+ byteArray& m_array;
|
|
+};
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
+
|
|
+#endif // VMIME_UTILITY_OUTPUTSTREAMBYTEARRAYADAPTER_HPP_INCLUDED
|
|
+
|
|
diff --git a/vmime/utility/outputStreamSocketAdapter.hpp b/vmime/utility/outputStreamSocketAdapter.hpp
|
|
new file mode 100644
|
|
index 0000000..e3d3eb0
|
|
--- /dev/null
|
|
+++ b/vmime/utility/outputStreamSocketAdapter.hpp
|
|
@@ -0,0 +1,75 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#ifndef VMIME_UTILITY_OUTPUTSTREAMSOCKETADAPTER_HPP_INCLUDED
|
|
+#define VMIME_UTILITY_OUTPUTSTREAMSOCKETADAPTER_HPP_INCLUDED
|
|
+
|
|
+
|
|
+#include "vmime/utility/outputStream.hpp"
|
|
+
|
|
+
|
|
+#if VMIME_HAVE_MESSAGING_FEATURES
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace net {
|
|
+ class socket; // forward reference
|
|
+} // net
|
|
+} // vmime
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+/** An output stream that is connected to a socket.
|
|
+ */
|
|
+
|
|
+class outputStreamSocketAdapter : public outputStream
|
|
+{
|
|
+public:
|
|
+
|
|
+ outputStreamSocketAdapter(net::socket& sok);
|
|
+
|
|
+ void write(const value_type* const data, const size_type count);
|
|
+ void flush();
|
|
+
|
|
+ size_type getBlockSize();
|
|
+
|
|
+private:
|
|
+
|
|
+ outputStreamSocketAdapter(const outputStreamSocketAdapter&);
|
|
+
|
|
+ net::socket& m_socket;
|
|
+};
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
+
|
|
+#endif // VMIME_HAVE_MESSAGING_FEATURES
|
|
+
|
|
+
|
|
+#endif // VMIME_UTILITY_OUTPUTSTREAMSOCKETADAPTER_HPP_INCLUDED
|
|
+
|
|
diff --git a/vmime/utility/outputStreamStringAdapter.hpp b/vmime/utility/outputStreamStringAdapter.hpp
|
|
new file mode 100644
|
|
index 0000000..8c8b304
|
|
--- /dev/null
|
|
+++ b/vmime/utility/outputStreamStringAdapter.hpp
|
|
@@ -0,0 +1,59 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#ifndef VMIME_UTILITY_OUTPUTSTREAMSTRINGADAPTER_HPP_INCLUDED
|
|
+#define VMIME_UTILITY_OUTPUTSTREAMSTRINGADAPTER_HPP_INCLUDED
|
|
+
|
|
+
|
|
+#include "vmime/utility/outputStream.hpp"
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+/** An adapter class for string output.
|
|
+ */
|
|
+
|
|
+class outputStreamStringAdapter : public outputStream
|
|
+{
|
|
+public:
|
|
+
|
|
+ outputStreamStringAdapter(string& buffer);
|
|
+
|
|
+ void write(const value_type* const data, const size_type count);
|
|
+ void flush();
|
|
+
|
|
+size_type getBlockSize(){return 8192;}
|
|
+private:
|
|
+
|
|
+ string& m_buffer;
|
|
+};
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
+
|
|
+#endif // VMIME_UTILITY_OUTPUTSTREAMSTRINGADAPTER_HPP_INCLUDED
|
|
+
|
|
diff --git a/vmime/utility/stream.hpp b/vmime/utility/stream.hpp
|
|
index 1faab55..566ab9d 100644
|
|
--- a/vmime/utility/stream.hpp
|
|
+++ b/vmime/utility/stream.hpp
|
|
@@ -25,40 +25,22 @@
|
|
#define VMIME_UTILITY_STREAM_HPP_INCLUDED
|
|
|
|
|
|
-#include <istream>
|
|
-#include <ostream>
|
|
#include <sstream>
|
|
|
|
#include "vmime/config.hpp"
|
|
#include "vmime/types.hpp"
|
|
-
|
|
-#include "vmime/utility/progressListener.hpp"
|
|
-
|
|
-
|
|
-#if VMIME_HAVE_MESSAGING_FEATURES
|
|
- namespace vmime {
|
|
- namespace net {
|
|
- class socket; // forward reference
|
|
- } // net
|
|
- } // vmime
|
|
-#endif
|
|
-
|
|
-#if defined(_MSC_VER) && (_MSC_VER <= 1200) // VC++6
|
|
-# include <cstring>
|
|
-#endif
|
|
+#include "vmime/base.hpp"
|
|
|
|
|
|
namespace vmime {
|
|
namespace utility {
|
|
|
|
|
|
-class stringProxy;
|
|
-
|
|
|
|
/** Base class for input/output stream.
|
|
*/
|
|
|
|
-class stream : public object
|
|
+class stream : public object, private noncopyable
|
|
{
|
|
public:
|
|
|
|
@@ -81,365 +63,6 @@ public:
|
|
};
|
|
|
|
|
|
-
|
|
-/** Simple output stream.
|
|
- */
|
|
-
|
|
-class outputStream : public stream
|
|
-{
|
|
-public:
|
|
-
|
|
- /** Write data to the stream.
|
|
- *
|
|
- * @param data buffer containing data to write
|
|
- * @param count number of bytes to write
|
|
- */
|
|
- virtual void write(const value_type* const data, const size_type count) = 0;
|
|
-
|
|
- /** Flush this output stream and forces any buffered output
|
|
- * bytes to be written out to the stream.
|
|
- */
|
|
- virtual void flush() = 0;
|
|
-};
|
|
-
|
|
-
|
|
-
|
|
-/** Simple input stream.
|
|
- */
|
|
-
|
|
-class inputStream : public stream
|
|
-{
|
|
-public:
|
|
-
|
|
- /** Test for end of stream (no more data to read).
|
|
- *
|
|
- * @return true if we have reached the end of stream, false otherwise
|
|
- */
|
|
- virtual bool eof() const = 0;
|
|
-
|
|
- /** Set the read pointer to the beginning of the stream.
|
|
- *
|
|
- * @warning WARNING: this may not work for all stream types.
|
|
- */
|
|
- virtual void reset() = 0;
|
|
-
|
|
- /** Read data from the stream.
|
|
- *
|
|
- * @param data will receive the data read
|
|
- * @param count maximum number of bytes to read
|
|
- * @return number of bytes read
|
|
- */
|
|
- virtual size_type read(value_type* const data, const size_type count) = 0;
|
|
-
|
|
- /** Skip a number of bytes.
|
|
- *
|
|
- * @param count maximum number of bytes to ignore
|
|
- * @return number of bytes skipped
|
|
- */
|
|
- virtual size_type skip(const size_type count) = 0;
|
|
-};
|
|
-
|
|
-
|
|
-
|
|
-// Helpers functions
|
|
-
|
|
-outputStream& operator<<(outputStream& os, const string& str);
|
|
-outputStream& operator<<(outputStream& os, const stream::value_type c);
|
|
-
|
|
-
|
|
-#if defined(_MSC_VER) && (_MSC_VER <= 1200) // Internal compiler error with VC++6
|
|
-
|
|
-inline outputStream& operator<<(outputStream& os, const char* str)
|
|
-{
|
|
- os.write(str, ::strlen(str));
|
|
- return (os);
|
|
-}
|
|
-
|
|
-#else
|
|
-
|
|
-template <int N>
|
|
-outputStream& operator<<(outputStream& os, const char (&str)[N])
|
|
-{
|
|
- os.write(str, N - 1);
|
|
- return (os);
|
|
-}
|
|
-
|
|
-#endif // defined(_MSC_VER) && (_MSC_VER <= 1200)
|
|
-
|
|
-
|
|
-template <typename T>
|
|
-outputStream& operator<<(outputStream& os, const T& t)
|
|
-{
|
|
- std::ostringstream oss;
|
|
- oss.imbue(std::locale::classic()); // no formatting
|
|
-
|
|
- oss << t;
|
|
-
|
|
- os << oss.str();
|
|
-
|
|
- return (os);
|
|
-}
|
|
-
|
|
-
|
|
-/** Copy data from one stream into another stream using a buffered method.
|
|
- *
|
|
- * @param is input stream (source data)
|
|
- * @param os output stream (destination for data)
|
|
- * @return number of bytes copied
|
|
- */
|
|
-
|
|
-stream::size_type bufferedStreamCopy(inputStream& is, outputStream& os);
|
|
-
|
|
-/** Copy data from one stream into another stream using a buffered method
|
|
- * and notify progress state of the operation.
|
|
- *
|
|
- * @param is input stream (source data)
|
|
- * @param os output stream (destination for data)
|
|
- * @param length predicted number of bytes to copy
|
|
- * @param progress listener to notify
|
|
- * @return number of bytes copied
|
|
- */
|
|
-
|
|
-stream::size_type bufferedStreamCopy(inputStream& is, outputStream& os,
|
|
- const stream::size_type length, progressListener* progress);
|
|
-
|
|
-
|
|
-// Adapters
|
|
-
|
|
-
|
|
-/** An adapter class for C++ standard output streams.
|
|
- */
|
|
-
|
|
-class outputStreamAdapter : public outputStream
|
|
-{
|
|
-public:
|
|
-
|
|
- /** @param os output stream to wrap
|
|
- */
|
|
- outputStreamAdapter(std::ostream& os);
|
|
-
|
|
- void write(const value_type* const data, const size_type count);
|
|
- void flush();
|
|
-
|
|
-private:
|
|
-
|
|
- std::ostream& m_stream;
|
|
-};
|
|
-
|
|
-
|
|
-/** An adapter class for string output.
|
|
- */
|
|
-
|
|
-class outputStreamStringAdapter : public outputStream
|
|
-{
|
|
-public:
|
|
-
|
|
- outputStreamStringAdapter(string& buffer);
|
|
-
|
|
- void write(const value_type* const data, const size_type count);
|
|
- void flush();
|
|
-
|
|
-size_type getBlockSize(){return 8192;}
|
|
-private:
|
|
-
|
|
- string& m_buffer;
|
|
-};
|
|
-
|
|
-
|
|
-/** An adapter class for byte array output.
|
|
- */
|
|
-
|
|
-class outputStreamByteArrayAdapter : public outputStream
|
|
-{
|
|
-public:
|
|
-
|
|
- outputStreamByteArrayAdapter(byteArray& array);
|
|
-
|
|
- void write(const value_type* const data, const size_type count);
|
|
- void flush();
|
|
-
|
|
-private:
|
|
-
|
|
- byteArray& m_array;
|
|
-};
|
|
-
|
|
-
|
|
-/** An adapter class for C++ standard input streams.
|
|
- */
|
|
-
|
|
-class inputStreamAdapter : public inputStream
|
|
-{
|
|
-public:
|
|
-
|
|
- /** @param is input stream to wrap
|
|
- */
|
|
- inputStreamAdapter(std::istream& is);
|
|
-
|
|
- bool eof() const;
|
|
- void reset();
|
|
- size_type read(value_type* const data, const size_type count);
|
|
- size_type skip(const size_type count);
|
|
-
|
|
-private:
|
|
-
|
|
- std::istream& m_stream;
|
|
-};
|
|
-
|
|
-
|
|
-/** An adapter class for string input.
|
|
- */
|
|
-
|
|
-class inputStreamStringAdapter : public inputStream
|
|
-{
|
|
-public:
|
|
-
|
|
- inputStreamStringAdapter(const string& buffer);
|
|
- inputStreamStringAdapter(const string& buffer, const string::size_type begin, const string::size_type end);
|
|
-
|
|
- bool eof() const;
|
|
- void reset();
|
|
- size_type read(value_type* const data, const size_type count);
|
|
- size_type skip(const size_type count);
|
|
-
|
|
-private:
|
|
-
|
|
- inputStreamStringAdapter(const inputStreamStringAdapter&);
|
|
-
|
|
- const string m_buffer; // do _NOT_ keep a reference...
|
|
- const string::size_type m_begin;
|
|
- const string::size_type m_end;
|
|
- string::size_type m_pos;
|
|
-};
|
|
-
|
|
-
|
|
-/** An adapter class for stringProxy input.
|
|
- */
|
|
-
|
|
-class inputStreamStringProxyAdapter : public inputStream
|
|
-{
|
|
-public:
|
|
-
|
|
- /** @param buffer stringProxy object to wrap
|
|
- */
|
|
- inputStreamStringProxyAdapter(const stringProxy& buffer);
|
|
-
|
|
- bool eof() const;
|
|
- void reset();
|
|
- size_type read(value_type* const data, const size_type count);
|
|
- size_type skip(const size_type count);
|
|
-
|
|
-private:
|
|
-
|
|
- inputStreamStringProxyAdapter(const inputStreamStringProxyAdapter&);
|
|
-
|
|
- const stringProxy& m_buffer;
|
|
- string::size_type m_pos;
|
|
-};
|
|
-
|
|
-
|
|
-/** An adapter class for pointer to C++ standard input stream.
|
|
- */
|
|
-
|
|
-class inputStreamPointerAdapter : public inputStream
|
|
-{
|
|
-public:
|
|
-
|
|
- /** @param is input stream to wrap
|
|
- * @param own if set to 'true', the pointer will be deleted when
|
|
- * this object is destroyed
|
|
- */
|
|
- inputStreamPointerAdapter(std::istream* is, const bool own = true);
|
|
- ~inputStreamPointerAdapter();
|
|
-
|
|
- bool eof() const;
|
|
- void reset();
|
|
- size_type read(value_type* const data, const size_type count);
|
|
- size_type skip(const size_type count);
|
|
-
|
|
-private:
|
|
-
|
|
- inputStreamPointerAdapter(const inputStreamPointerAdapter&);
|
|
-
|
|
- std::istream* m_stream;
|
|
- const bool m_own;
|
|
-};
|
|
-
|
|
-
|
|
-/** An adapter class for reading from an array of bytes.
|
|
- */
|
|
-
|
|
-class inputStreamByteBufferAdapter : public inputStream
|
|
-{
|
|
-public:
|
|
-
|
|
- inputStreamByteBufferAdapter(const byte_t* buffer, size_type length);
|
|
-
|
|
- bool eof() const;
|
|
- void reset();
|
|
- size_type read(value_type* const data, const size_type count);
|
|
- size_type skip(const size_type count);
|
|
-
|
|
-private:
|
|
-
|
|
- const byte_t* m_buffer;
|
|
- const size_type m_length;
|
|
-
|
|
- size_type m_pos;
|
|
-};
|
|
-
|
|
-
|
|
-#if VMIME_HAVE_MESSAGING_FEATURES
|
|
-
|
|
-
|
|
-/** An output stream that is connected to a socket.
|
|
- */
|
|
-
|
|
-class outputStreamSocketAdapter : public outputStream
|
|
-{
|
|
-public:
|
|
-
|
|
- outputStreamSocketAdapter(net::socket& sok);
|
|
-
|
|
- void write(const value_type* const data, const size_type count);
|
|
- void flush();
|
|
-
|
|
- size_type getBlockSize();
|
|
-
|
|
-private:
|
|
-
|
|
- outputStreamSocketAdapter(const outputStreamSocketAdapter&);
|
|
-
|
|
- net::socket& m_socket;
|
|
-};
|
|
-
|
|
-
|
|
-/** An input stream that is connected to a socket.
|
|
- */
|
|
-
|
|
-class inputStreamSocketAdapter : public inputStream
|
|
-{
|
|
-public:
|
|
-
|
|
- inputStreamSocketAdapter(net::socket& sok);
|
|
-
|
|
- bool eof() const;
|
|
- void reset();
|
|
- size_type read(value_type* const data, const size_type count);
|
|
- size_type skip(const size_type count);
|
|
-
|
|
- size_type getBlockSize();
|
|
-
|
|
-private:
|
|
-
|
|
- inputStreamSocketAdapter(const inputStreamSocketAdapter&);
|
|
-
|
|
- net::socket& m_socket;
|
|
-};
|
|
-
|
|
-
|
|
-#endif // VMIME_HAVE_MESSAGING_FEATURES
|
|
-
|
|
-
|
|
} // utility
|
|
} // vmime
|
|
|
|
diff --git a/vmime/utility/streamUtils.hpp b/vmime/utility/streamUtils.hpp
|
|
new file mode 100644
|
|
index 0000000..cdf70aa
|
|
--- /dev/null
|
|
+++ b/vmime/utility/streamUtils.hpp
|
|
@@ -0,0 +1,66 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#ifndef VMIME_UTILITY_STREAMUTILS_HPP_INCLUDED
|
|
+#define VMIME_UTILITY_STREAMUTILS_HPP_INCLUDED
|
|
+
|
|
+
|
|
+#include "vmime/utility/inputStream.hpp"
|
|
+#include "vmime/utility/outputStream.hpp"
|
|
+
|
|
+#include "vmime/utility/progressListener.hpp"
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+/** Copy data from one stream into another stream using a buffered method.
|
|
+ *
|
|
+ * @param is input stream (source data)
|
|
+ * @param os output stream (destination for data)
|
|
+ * @return number of bytes copied
|
|
+ */
|
|
+
|
|
+stream::size_type bufferedStreamCopy(inputStream& is, outputStream& os);
|
|
+
|
|
+/** Copy data from one stream into another stream using a buffered method
|
|
+ * and notify progress state of the operation.
|
|
+ *
|
|
+ * @param is input stream (source data)
|
|
+ * @param os output stream (destination for data)
|
|
+ * @param length predicted number of bytes to copy
|
|
+ * @param progress listener to notify
|
|
+ * @return number of bytes copied
|
|
+ */
|
|
+
|
|
+stream::size_type bufferedStreamCopy(inputStream& is, outputStream& os,
|
|
+ const stream::size_type length, progressListener* progress);
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
+
|
|
+#endif // VMIME_UTILITY_STREAMUTILS_HPP_INCLUDED
|
|
+
|
|
diff --git a/vmime/utility/stringProxy.hpp b/vmime/utility/stringProxy.hpp
|
|
index 21c65ea..66a6dfd 100644
|
|
--- a/vmime/utility/stringProxy.hpp
|
|
+++ b/vmime/utility/stringProxy.hpp
|
|
@@ -29,6 +29,7 @@
|
|
|
|
#include "vmime/types.hpp"
|
|
#include "vmime/utility/stream.hpp"
|
|
+#include "vmime/utility/outputStream.hpp"
|
|
#include "vmime/utility/progressListener.hpp"
|
|
|
|
|
|
diff --git a/vmime/vmime.hpp b/vmime/vmime.hpp
|
|
index f187b9e..fd04853 100644
|
|
--- a/vmime/vmime.hpp
|
|
+++ b/vmime/vmime.hpp
|
|
@@ -68,6 +68,22 @@
|
|
// Encoders
|
|
#include "vmime/utility/encoder/encoderFactory.hpp"
|
|
|
|
+// Streams
|
|
+#include "vmime/utility/filteredStream.hpp"
|
|
+#include "vmime/utility/inputStream.hpp"
|
|
+#include "vmime/utility/inputStreamAdapter.hpp"
|
|
+#include "vmime/utility/inputStreamByteBufferAdapter.hpp"
|
|
+#include "vmime/utility/inputStreamPointerAdapter.hpp"
|
|
+#include "vmime/utility/inputStreamSocketAdapter.hpp"
|
|
+#include "vmime/utility/inputStreamStringAdapter.hpp"
|
|
+#include "vmime/utility/inputStreamStringProxyAdapter.hpp"
|
|
+#include "vmime/utility/outputStream.hpp"
|
|
+#include "vmime/utility/outputStreamAdapter.hpp"
|
|
+#include "vmime/utility/outputStreamByteArrayAdapter.hpp"
|
|
+#include "vmime/utility/outputStreamSocketAdapter.hpp"
|
|
+#include "vmime/utility/outputStreamStringAdapter.hpp"
|
|
+#include "vmime/utility/streamUtils.hpp"
|
|
+
|
|
// Message builder/parser
|
|
#include "vmime/messageBuilder.hpp"
|
|
#include "vmime/messageParser.hpp"
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From be30b47f09c5358db2ac8e42fa2bb4a14ec24c51 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Mon, 16 Apr 2012 22:32:33 +0200
|
|
Subject: [PATCH 37/39] Added ability to parse directly from an input stream
|
|
(eg. file). This allows very big messages to be
|
|
parsed without loading the whole message data into
|
|
memory.
|
|
|
|
|
|
diff --git a/ChangeLog b/ChangeLog
|
|
index 8fdcdb0..1b5b2cf 100644
|
|
--- a/ChangeLog
|
|
+++ b/ChangeLog
|
|
@@ -2,6 +2,12 @@
|
|
VERSION 0.9.2svn
|
|
================
|
|
|
|
+2012-04-16 Vincent Richard <vincent@vincent-richard.net>
|
|
+
|
|
+ * MIME Parser can now operate directly on an input stream (eg. file).
|
|
+ This allows very big messages to be parsed without loading the whole
|
|
+ message data into memory.
|
|
+
|
|
2010-11-16 Vincent Richard <vincent@vincent-richard.net>
|
|
|
|
* Started version 0.9.2.
|
|
diff --git a/SConstruct b/SConstruct
|
|
index ea5c4eb..2690172 100644
|
|
--- a/SConstruct
|
|
+++ b/SConstruct
|
|
@@ -153,11 +153,14 @@ libvmime_sources = [
|
|
'utility/inputStreamSocketAdapter.cpp', 'utility/inputStreamSocketAdapter.hpp',
|
|
'utility/inputStreamStringAdapter.cpp', 'utility/inputStreamStringAdapter.hpp',
|
|
'utility/inputStreamStringProxyAdapter.cpp', 'utility/inputStreamStringProxyAdapter.hpp',
|
|
+ 'utility/seekableInputStream.hpp',
|
|
+ 'utility/seekableInputStreamRegionAdapter.cpp', 'utility/seekableInputStreamRegionAdapter.hpp',
|
|
'utility/outputStream.cpp', 'utility/outputStream.hpp',
|
|
'utility/outputStreamAdapter.cpp', 'utility/outputStreamAdapter.hpp',
|
|
'utility/outputStreamByteArrayAdapter.cpp', 'utility/outputStreamByteArrayAdapter.hpp',
|
|
'utility/outputStreamSocketAdapter.cpp', 'utility/outputStreamSocketAdapter.hpp',
|
|
'utility/outputStreamStringAdapter.cpp', 'utility/outputStreamStringAdapter.hpp',
|
|
+ 'utility/parserInputStreamAdapter.cpp', 'utility/parserInputStreamAdapter.hpp',
|
|
'utility/stringProxy.cpp', 'utility/stringProxy.hpp',
|
|
'utility/stringUtils.cpp', 'utility/stringUtils.hpp',
|
|
'utility/url.cpp', 'utility/url.hpp',
|
|
diff --git a/src/addressList.cpp b/src/addressList.cpp
|
|
index 31a2a3d..f06460d 100644
|
|
--- a/src/addressList.cpp
|
|
+++ b/src/addressList.cpp
|
|
@@ -50,7 +50,7 @@ addressList::~addressList()
|
|
}
|
|
|
|
|
|
-void addressList::parse(const string& buffer, const string::size_type position,
|
|
+void addressList::parseImpl(const string& buffer, const string::size_type position,
|
|
const string::size_type end, string::size_type* newPosition)
|
|
{
|
|
removeAllAddresses();
|
|
@@ -72,7 +72,7 @@ void addressList::parse(const string& buffer, const string::size_type position,
|
|
}
|
|
|
|
|
|
-void addressList::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
+void addressList::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
{
|
|
string::size_type pos = curLinePos;
|
|
@@ -248,9 +248,9 @@ const std::vector <ref <address> > addressList::getAddressList()
|
|
}
|
|
|
|
|
|
-const std::vector <ref <const component> > addressList::getChildComponents() const
|
|
+const std::vector <ref <component> > addressList::getChildComponents()
|
|
{
|
|
- std::vector <ref <const component> > list;
|
|
+ std::vector <ref <component> > list;
|
|
|
|
copy_vector(m_list, list);
|
|
|
|
diff --git a/src/body.cpp b/src/body.cpp
|
|
index 9d7d57f..732fa8b 100644
|
|
--- a/src/body.cpp
|
|
+++ b/src/body.cpp
|
|
@@ -31,10 +31,13 @@
|
|
|
|
#include "vmime/utility/random.hpp"
|
|
|
|
+#include "vmime/utility/seekableInputStreamRegionAdapter.hpp"
|
|
+
|
|
#include "vmime/parserHelpers.hpp"
|
|
|
|
#include "vmime/emptyContentHandler.hpp"
|
|
#include "vmime/stringContentHandler.hpp"
|
|
+#include "vmime/streamContentHandler.hpp"
|
|
|
|
|
|
namespace vmime
|
|
@@ -52,11 +55,28 @@ body::~body()
|
|
}
|
|
|
|
|
|
-void body::parse(const string& buffer, const string::size_type position,
|
|
- const string::size_type end, string::size_type* newPosition)
|
|
+void body::parseImpl
|
|
+ (ref <utility::parserInputStreamAdapter> parser,
|
|
+ const utility::stream::size_type position,
|
|
+ const utility::stream::size_type end,
|
|
+ utility::stream::size_type* newPosition)
|
|
{
|
|
removeAllParts();
|
|
|
|
+ m_prologText.clear();
|
|
+ m_epilogText.clear();
|
|
+
|
|
+ if (end == position)
|
|
+ {
|
|
+
|
|
+ setParsedBounds(position, end);
|
|
+
|
|
+ if (newPosition)
|
|
+ *newPosition = end;
|
|
+
|
|
+ return;
|
|
+ }
|
|
+
|
|
// Check whether the body is a MIME-multipart
|
|
bool isMultipart = false;
|
|
string boundary;
|
|
@@ -80,37 +100,61 @@ void body::parse(const string& buffer, const string::size_type position,
|
|
{
|
|
// No "boundary" parameter specified: we can try to
|
|
// guess it by scanning the body contents...
|
|
- string::size_type pos = buffer.find("\n--", position);
|
|
+ utility::stream::size_type pos = position;
|
|
+
|
|
+ parser->seek(pos);
|
|
+
|
|
+ if (pos + 2 < end && parser->matchBytes("--", 2))
|
|
+ {
|
|
+ pos += 2;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ pos = parser->findNext("\n--", position);
|
|
|
|
- if ((pos != string::npos) && (pos < end))
|
|
+ if ((pos != utility::stream::npos) && (pos + 3 < end))
|
|
+ pos += 3; // skip \n--
|
|
+ }
|
|
+
|
|
+ if ((pos != utility::stream::npos) && (pos < end))
|
|
{
|
|
- pos += 3;
|
|
+ parser->seek(pos);
|
|
|
|
- const string::size_type start = pos;
|
|
+ // Read some bytes after boundary separator
|
|
+ utility::stream::value_type buffer[256];
|
|
+ const utility::stream::size_type bufferLen =
|
|
+ parser->read(buffer, std::min(end - pos, sizeof(buffer) / sizeof(buffer[0])));
|
|
|
|
- char_t c = buffer[pos];
|
|
- string::size_type length = 0;
|
|
+ buffer[sizeof(buffer) / sizeof(buffer[0]) - 1] = '\0';
|
|
|
|
+ // Extract boundary from buffer (stop at first CR or LF).
|
|
// We have to stop after a reasonnably long boundary length (100)
|
|
// not to take the whole body contents for a boundary...
|
|
- while (pos < end && length < 100 && !(c == '\r' || c == '\n'))
|
|
+ string::value_type boundaryBytes[100];
|
|
+ string::size_type boundaryLen = 0;
|
|
+
|
|
+ for (string::value_type c = buffer[0] ;
|
|
+ boundaryLen < bufferLen && boundaryLen < 100 && !(c == '\r' || c == '\n') ;
|
|
+ c = buffer[++boundaryLen])
|
|
{
|
|
- ++length;
|
|
- c = buffer[pos++];
|
|
+ boundaryBytes[boundaryLen] = buffer[boundaryLen];
|
|
}
|
|
|
|
- if (pos < end && length < 100)
|
|
+ if (boundaryLen >= 1 && boundaryLen < 100)
|
|
{
|
|
// RFC #1521, Page 31:
|
|
// "...the boundary parameter, which consists of 1 to 70
|
|
// characters from a set of characters known to be very
|
|
// robust through email gateways, and NOT ending with
|
|
// white space..."
|
|
- while (pos != start && parserHelpers::isSpace(buffer[pos - 1]))
|
|
- --pos;
|
|
-
|
|
- boundary = string(buffer.begin() + start,
|
|
- buffer.begin() + pos);
|
|
+ while (boundaryLen != 0 &&
|
|
+ parserHelpers::isSpace(boundaryBytes[boundaryLen - 1]))
|
|
+ {
|
|
+ boundaryLen--;
|
|
+ }
|
|
+
|
|
+ if (boundaryLen >= 1)
|
|
+ boundary = string(boundaryBytes, boundaryBytes + boundaryLen);
|
|
}
|
|
}
|
|
}
|
|
@@ -126,51 +170,79 @@ void body::parse(const string& buffer, const string::size_type position,
|
|
{
|
|
const string boundarySep("--" + boundary);
|
|
|
|
- string::size_type partStart = position;
|
|
- string::size_type pos = position;
|
|
+ utility::stream::size_type partStart = position;
|
|
+ utility::stream::size_type pos = position;
|
|
|
|
bool lastPart = false;
|
|
|
|
- while (pos != string::npos && pos < end)
|
|
+ while (pos != utility::stream::npos && pos < end)
|
|
{
|
|
- pos = buffer.find(boundarySep, pos);
|
|
-
|
|
- if (pos == string::npos ||
|
|
- ((pos == 0 || buffer[pos - 1] == '\n') &&
|
|
- (buffer[pos + boundarySep.length()] == '\r' ||
|
|
- buffer[pos + boundarySep.length()] == '\n' ||
|
|
- buffer[pos + boundarySep.length()] == '-'
|
|
- )
|
|
- )
|
|
- )
|
|
+ pos = parser->findNext(boundarySep, pos);
|
|
+
|
|
+ if (pos == utility::stream::npos)
|
|
+ break; // not found
|
|
+
|
|
+ if (pos != 0)
|
|
{
|
|
- break;
|
|
+ parser->seek(pos - 1);
|
|
+
|
|
+ if (parser->peekByte() != '\n')
|
|
+ {
|
|
+ // Boundary is not at a beginning of a line
|
|
+ pos++;
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ parser->skip(1 + boundarySep.length());
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ parser->seek(pos + boundarySep.length());
|
|
}
|
|
|
|
- // boundary not a beginning of line, or just a prefix of another, continue the search.
|
|
+ const utility::stream::value_type next = parser->peekByte();
|
|
+
|
|
+ if (next == '\r' || next == '\n' || next == '-')
|
|
+ break;
|
|
+
|
|
+ // Boundary is a prefix of another, continue the search
|
|
pos++;
|
|
}
|
|
|
|
- if (pos != string::npos && pos < end)
|
|
+ if (pos != utility::stream::npos && pos < end)
|
|
{
|
|
vmime::text text;
|
|
- text.parse(buffer, position, pos);
|
|
+ text.parse(parser, position, pos);
|
|
|
|
m_prologText = text.getWholeBuffer();
|
|
}
|
|
|
|
- for (int index = 0 ; !lastPart && (pos != string::npos) && (pos < end) ; ++index)
|
|
+ for (int index = 0 ; !lastPart && (pos != utility::stream::npos) && (pos < end) ; ++index)
|
|
{
|
|
- string::size_type partEnd = pos;
|
|
+ utility::stream::size_type partEnd = pos;
|
|
|
|
// Get rid of the [CR]LF just before the boundary string
|
|
- if (pos >= (position + 1) && buffer[pos - 1] == '\n') --partEnd;
|
|
- if (pos >= (position + 2) && buffer[pos - 2] == '\r') --partEnd;
|
|
+ if (pos >= (position + 1))
|
|
+ {
|
|
+ parser->seek(pos - 1);
|
|
+
|
|
+ if (parser->peekByte() == '\n')
|
|
+ --partEnd;
|
|
+ }
|
|
+
|
|
+ if (pos >= (position + 2))
|
|
+ {
|
|
+ parser->seek(pos - 2);
|
|
+
|
|
+ if (parser->peekByte() == '\r')
|
|
+ --partEnd;
|
|
+ }
|
|
|
|
// Check whether it is the last part (boundary terminated by "--")
|
|
pos += boundarySep.length();
|
|
+ parser->seek(pos);
|
|
|
|
- if (pos + 1 < end && buffer[pos] == '-' && buffer[pos + 1] == '-')
|
|
+ if (pos + 1 < end && parser->matchBytes("--", 2))
|
|
{
|
|
lastPart = true;
|
|
pos += 2;
|
|
@@ -180,15 +252,15 @@ void body::parse(const string& buffer, const string::size_type position,
|
|
// "...(If a boundary appears to end with white space, the
|
|
// white space must be presumed to have been added by a
|
|
// gateway, and must be deleted.)..."
|
|
- while (pos < end && (buffer[pos] == ' ' || buffer[pos] == '\t'))
|
|
- ++pos;
|
|
+ parser->seek(pos);
|
|
+ pos += parser->skipIf(parserHelpers::isSpaceOrTab, end);
|
|
|
|
// End of boundary line
|
|
- if (pos + 1 < end && buffer[pos] == '\r' && buffer[pos + 1] =='\n')
|
|
+ if (pos + 1 < end && parser->matchBytes("\r\n", 2))
|
|
{
|
|
pos += 2;
|
|
}
|
|
- else if (pos < end && buffer[pos] == '\n')
|
|
+ else if (pos < end && parser->peekByte() == '\n')
|
|
{
|
|
++pos;
|
|
}
|
|
@@ -202,7 +274,7 @@ void body::parse(const string& buffer, const string::size_type position,
|
|
if (partEnd < partStart)
|
|
std::swap(partStart, partEnd);
|
|
|
|
- part->parse(buffer, partStart, partEnd, NULL);
|
|
+ part->parse(parser, partStart, partEnd, NULL);
|
|
part->m_parent = m_part;
|
|
|
|
m_parts.push_back(part);
|
|
@@ -210,23 +282,37 @@ void body::parse(const string& buffer, const string::size_type position,
|
|
|
|
partStart = pos;
|
|
|
|
- while (pos != string::npos && pos < end)
|
|
+ while (pos != utility::stream::npos && pos < end)
|
|
{
|
|
- pos = buffer.find(boundarySep, pos);
|
|
-
|
|
- if (pos == string::npos ||
|
|
- ((pos == 0 || buffer[pos - 1] == '\n') &&
|
|
- (buffer[pos + boundarySep.length()] == '\r' ||
|
|
- buffer[pos + boundarySep.length()] == '\n' ||
|
|
- buffer[pos + boundarySep.length()] == '-'
|
|
- )
|
|
- )
|
|
- )
|
|
+ pos = parser->findNext(boundarySep, pos);
|
|
+
|
|
+ if (pos == utility::stream::npos)
|
|
+ break; // not found
|
|
+
|
|
+ if (pos != 0)
|
|
{
|
|
- break;
|
|
+ parser->seek(pos - 1);
|
|
+
|
|
+ if (parser->peekByte() != '\n')
|
|
+ {
|
|
+ // Boundary is not at a beginning of a line
|
|
+ pos++;
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ parser->skip(1 + boundarySep.length());
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ parser->seek(pos + boundarySep.length());
|
|
}
|
|
|
|
- // boundary not a beginning of line, or just a prefix of another, continue the search.
|
|
+ const utility::stream::value_type next = parser->peekByte();
|
|
+
|
|
+ if (next == '\r' || next == '\n' || next == '-')
|
|
+ break;
|
|
+
|
|
+ // Boundary is a prefix of another, continue the search
|
|
pos++;
|
|
}
|
|
}
|
|
@@ -234,13 +320,13 @@ void body::parse(const string& buffer, const string::size_type position,
|
|
m_contents = vmime::create <emptyContentHandler>();
|
|
|
|
// Last part was not found: recover from missing boundary
|
|
- if (!lastPart && pos == string::npos)
|
|
+ if (!lastPart && pos == utility::stream::npos)
|
|
{
|
|
ref <bodyPart> part = vmime::create <bodyPart>();
|
|
|
|
try
|
|
{
|
|
- part->parse(buffer, partStart, end);
|
|
+ part->parse(parser, partStart, end);
|
|
}
|
|
catch (std::exception&)
|
|
{
|
|
@@ -255,7 +341,7 @@ void body::parse(const string& buffer, const string::size_type position,
|
|
else if (partStart < end)
|
|
{
|
|
vmime::text text;
|
|
- text.parse(buffer, partStart, end);
|
|
+ text.parse(parser, partStart, end);
|
|
|
|
m_epilogText = text.getWholeBuffer();
|
|
}
|
|
@@ -282,7 +368,13 @@ void body::parse(const string& buffer, const string::size_type position,
|
|
}
|
|
|
|
// Extract the (encoded) contents
|
|
- m_contents = vmime::create <stringContentHandler>(buffer, position, end, enc);
|
|
+ const utility::stream::size_type length = end - position;
|
|
+
|
|
+ ref <utility::inputStream> contentStream =
|
|
+ vmime::create <utility::seekableInputStreamRegionAdapter>
|
|
+ (parser->getUnderlyingStream(), position, length);
|
|
+
|
|
+ m_contents = vmime::create <streamContentHandler>(contentStream, length, enc);
|
|
}
|
|
|
|
setParsedBounds(position, end);
|
|
@@ -292,7 +384,7 @@ void body::parse(const string& buffer, const string::size_type position,
|
|
}
|
|
|
|
|
|
-void body::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
+void body::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
|
const string::size_type /* curLinePos */, string::size_type* newLinePos) const
|
|
{
|
|
// MIME-Multipart
|
|
@@ -862,9 +954,9 @@ const std::vector <ref <bodyPart> > body::getPartList()
|
|
}
|
|
|
|
|
|
-const std::vector <ref <const component> > body::getChildComponents() const
|
|
+const std::vector <ref <component> > body::getChildComponents()
|
|
{
|
|
- std::vector <ref <const component> > list;
|
|
+ std::vector <ref <component> > list;
|
|
|
|
copy_vector(m_parts, list);
|
|
|
|
diff --git a/src/bodyPart.cpp b/src/bodyPart.cpp
|
|
index 7d60461..522cbb2 100644
|
|
--- a/src/bodyPart.cpp
|
|
+++ b/src/bodyPart.cpp
|
|
@@ -46,15 +46,18 @@ bodyPart::bodyPart(weak_ref <vmime::bodyPart> parentPart)
|
|
}
|
|
|
|
|
|
-void bodyPart::parse(const string& buffer, const string::size_type position,
|
|
- const string::size_type end, string::size_type* newPosition)
|
|
+void bodyPart::parseImpl
|
|
+ (ref <utility::parserInputStreamAdapter> parser,
|
|
+ const utility::stream::size_type position,
|
|
+ const utility::stream::size_type end,
|
|
+ utility::stream::size_type* newPosition)
|
|
{
|
|
// Parse the headers
|
|
string::size_type pos = position;
|
|
- m_header->parse(buffer, pos, end, &pos);
|
|
+ m_header->parse(parser, pos, end, &pos);
|
|
|
|
// Parse the body contents
|
|
- m_body->parse(buffer, pos, end, NULL);
|
|
+ m_body->parse(parser, pos, end, NULL);
|
|
|
|
setParsedBounds(position, end);
|
|
|
|
@@ -63,7 +66,7 @@ void bodyPart::parse(const string& buffer, const string::size_type position,
|
|
}
|
|
|
|
|
|
-void bodyPart::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
+void bodyPart::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
|
const string::size_type /* curLinePos */, string::size_type* newLinePos) const
|
|
{
|
|
m_header->generate(os, maxLineLength);
|
|
@@ -142,9 +145,9 @@ ref <const bodyPart> bodyPart::getParentPart() const
|
|
}
|
|
|
|
|
|
-const std::vector <ref <const component> > bodyPart::getChildComponents() const
|
|
+const std::vector <ref <component> > bodyPart::getChildComponents()
|
|
{
|
|
- std::vector <ref <const component> > list;
|
|
+ std::vector <ref <component> > list;
|
|
|
|
list.push_back(m_header);
|
|
list.push_back(m_body);
|
|
diff --git a/src/charset.cpp b/src/charset.cpp
|
|
index 0fda450..705664f 100644
|
|
--- a/src/charset.cpp
|
|
+++ b/src/charset.cpp
|
|
@@ -57,7 +57,7 @@ charset::charset(const char* name)
|
|
}
|
|
|
|
|
|
-void charset::parse(const string& buffer, const string::size_type position,
|
|
+void charset::parseImpl(const string& buffer, const string::size_type position,
|
|
const string::size_type end, string::size_type* newPosition)
|
|
{
|
|
m_name = utility::stringUtils::trim
|
|
@@ -74,7 +74,7 @@ void charset::parse(const string& buffer, const string::size_type position,
|
|
}
|
|
|
|
|
|
-void charset::generate(utility::outputStream& os, const string::size_type /* maxLineLength */,
|
|
+void charset::generateImpl(utility::outputStream& os, const string::size_type /* maxLineLength */,
|
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
{
|
|
os << m_name;
|
|
@@ -142,9 +142,9 @@ void charset::copyFrom(const component& other)
|
|
}
|
|
|
|
|
|
-const std::vector <ref <const component> > charset::getChildComponents() const
|
|
+const std::vector <ref <component> > charset::getChildComponents()
|
|
{
|
|
- return std::vector <ref <const component> >();
|
|
+ return std::vector <ref <component> >();
|
|
}
|
|
|
|
|
|
diff --git a/src/component.cpp b/src/component.cpp
|
|
index 139cf66..e93aacf 100644
|
|
--- a/src/component.cpp
|
|
+++ b/src/component.cpp
|
|
@@ -23,6 +23,9 @@
|
|
|
|
#include "vmime/component.hpp"
|
|
#include "vmime/base.hpp"
|
|
+
|
|
+#include "vmime/utility/streamUtils.hpp"
|
|
+#include "vmime/utility/inputStreamStringAdapter.hpp"
|
|
#include "vmime/utility/outputStreamAdapter.hpp"
|
|
|
|
#include <sstream>
|
|
@@ -43,9 +46,102 @@ component::~component()
|
|
}
|
|
|
|
|
|
+void component::parse
|
|
+ (ref <utility::inputStream> inputStream, const utility::stream::size_type length)
|
|
+{
|
|
+ parse(inputStream, 0, length, NULL);
|
|
+}
|
|
+
|
|
+
|
|
+void component::parse
|
|
+ (ref <utility::inputStream> inputStream, const utility::stream::size_type position,
|
|
+ const utility::stream::size_type end, utility::stream::size_type* newPosition)
|
|
+{
|
|
+ m_parsedOffset = m_parsedLength = 0;
|
|
+
|
|
+ ref <utility::seekableInputStream> seekableStream =
|
|
+ inputStream.dynamicCast <utility::seekableInputStream>();
|
|
+
|
|
+ if (seekableStream == NULL || end == 0)
|
|
+ {
|
|
+ // Read the whole stream into a buffer
|
|
+ std::ostringstream oss;
|
|
+ utility::outputStreamAdapter ossAdapter(oss);
|
|
+
|
|
+ utility::bufferedStreamCopyRange(*inputStream, ossAdapter, position, end - position);
|
|
+
|
|
+ const string buffer = oss.str();
|
|
+ parseImpl(buffer, 0, buffer.length(), NULL);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ ref <utility::parserInputStreamAdapter> parser =
|
|
+ vmime::create <utility::parserInputStreamAdapter>(seekableStream);
|
|
+
|
|
+ parseImpl(parser, position, end, newPosition);
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
void component::parse(const string& buffer)
|
|
{
|
|
- parse(buffer, 0, buffer.length(), NULL);
|
|
+ m_parsedOffset = m_parsedLength = 0;
|
|
+
|
|
+ parseImpl(buffer, 0, buffer.length(), NULL);
|
|
+}
|
|
+
|
|
+
|
|
+void component::parse
|
|
+ (const string& buffer, const string::size_type position,
|
|
+ const string::size_type end, string::size_type* newPosition)
|
|
+{
|
|
+ m_parsedOffset = m_parsedLength = 0;
|
|
+
|
|
+ parseImpl(buffer, position, end, newPosition);
|
|
+}
|
|
+
|
|
+
|
|
+void component::offsetParsedBounds(const utility::stream::size_type offset)
|
|
+{
|
|
+ // Offset parsed bounds of this component
|
|
+ if (m_parsedLength != 0)
|
|
+ m_parsedOffset += offset;
|
|
+
|
|
+ // Offset parsed bounds of our children
|
|
+ std::vector <ref <component> > children = getChildComponents();
|
|
+
|
|
+ for (unsigned int i = 0, n = children.size() ; i < n ; ++i)
|
|
+ children[i]->offsetParsedBounds(offset);
|
|
+}
|
|
+
|
|
+
|
|
+void component::parseImpl
|
|
+ (ref <utility::parserInputStreamAdapter> parser, const utility::stream::size_type position,
|
|
+ const utility::stream::size_type end, utility::stream::size_type* newPosition)
|
|
+{
|
|
+ const std::string buffer = parser->extract(position, end);
|
|
+ parseImpl(buffer, 0, buffer.length(), newPosition);
|
|
+
|
|
+ // Recursivey offset parsed bounds on children
|
|
+ if (position != 0)
|
|
+ offsetParsedBounds(position);
|
|
+
|
|
+ if (newPosition != NULL)
|
|
+ *newPosition += position;
|
|
+}
|
|
+
|
|
+
|
|
+void component::parseImpl
|
|
+ (const string& buffer, const string::size_type position,
|
|
+ const string::size_type end, string::size_type* newPosition)
|
|
+{
|
|
+ ref <utility::seekableInputStream> stream =
|
|
+ vmime::create <utility::inputStreamStringAdapter>(buffer);
|
|
+
|
|
+ ref <utility::parserInputStreamAdapter> parser =
|
|
+ vmime::create <utility::parserInputStreamAdapter>(stream);
|
|
+
|
|
+ parseImpl(parser, position, end, newPosition);
|
|
}
|
|
|
|
|
|
@@ -61,6 +157,26 @@ const string component::generate(const string::size_type maxLineLength,
|
|
}
|
|
|
|
|
|
+void component::generate
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength,
|
|
+ const string::size_type curLinePos,
|
|
+ string::size_type* newLinePos) const
|
|
+{
|
|
+ generateImpl(os, maxLineLength, curLinePos, newLinePos);
|
|
+}
|
|
+
|
|
+
|
|
+void component::generate
|
|
+ (ref <utility::outputStream> os,
|
|
+ const string::size_type maxLineLength,
|
|
+ const string::size_type curLinePos,
|
|
+ string::size_type* newLinePos) const
|
|
+{
|
|
+ generateImpl(*os, maxLineLength, curLinePos, newLinePos);
|
|
+}
|
|
+
|
|
+
|
|
string::size_type component::getParsedOffset() const
|
|
{
|
|
return (m_parsedOffset);
|
|
@@ -80,22 +196,5 @@ void component::setParsedBounds(const string::size_type start, const string::siz
|
|
}
|
|
|
|
|
|
-const std::vector <ref <component> > component::getChildComponents()
|
|
-{
|
|
- const std::vector <ref <const component> > constList =
|
|
- const_cast <const component*>(this)->getChildComponents();
|
|
-
|
|
- std::vector <ref <component> > list;
|
|
-
|
|
- const std::vector <ref <const component> >::size_type count = constList.size();
|
|
+} // vmime
|
|
|
|
- list.resize(count);
|
|
-
|
|
- for (std::vector <ref <const component> >::size_type i = 0 ; i < count ; ++i)
|
|
- list[i] = constList[i].constCast <component>();
|
|
-
|
|
- return (list);
|
|
-}
|
|
-
|
|
-
|
|
-}
|
|
diff --git a/src/contentDisposition.cpp b/src/contentDisposition.cpp
|
|
index 0ab7c45..253dbba 100644
|
|
--- a/src/contentDisposition.cpp
|
|
+++ b/src/contentDisposition.cpp
|
|
@@ -47,7 +47,7 @@ contentDisposition::contentDisposition(const contentDisposition& type)
|
|
}
|
|
|
|
|
|
-void contentDisposition::parse(const string& buffer, const string::size_type position,
|
|
+void contentDisposition::parseImpl(const string& buffer, const string::size_type position,
|
|
const string::size_type end, string::size_type* newPosition)
|
|
{
|
|
m_name = utility::stringUtils::trim(utility::stringUtils::toLower
|
|
@@ -60,7 +60,7 @@ void contentDisposition::parse(const string& buffer, const string::size_type pos
|
|
}
|
|
|
|
|
|
-void contentDisposition::generate(utility::outputStream& os, const string::size_type /* maxLineLength */,
|
|
+void contentDisposition::generateImpl(utility::outputStream& os, const string::size_type /* maxLineLength */,
|
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
{
|
|
os << m_name;
|
|
@@ -122,9 +122,9 @@ void contentDisposition::setName(const string& name)
|
|
}
|
|
|
|
|
|
-const std::vector <ref <const component> > contentDisposition::getChildComponents() const
|
|
+const std::vector <ref <component> > contentDisposition::getChildComponents()
|
|
{
|
|
- return std::vector <ref <const component> >();
|
|
+ return std::vector <ref <component> >();
|
|
}
|
|
|
|
|
|
diff --git a/src/dateTime.cpp b/src/dateTime.cpp
|
|
index 089a900..0d97b2f 100644
|
|
--- a/src/dateTime.cpp
|
|
+++ b/src/dateTime.cpp
|
|
@@ -67,7 +67,7 @@ zone = "UT" / "GMT" ; Universal Time
|
|
*/
|
|
|
|
|
|
-void datetime::parse(const string& buffer, const string::size_type position,
|
|
+void datetime::parseImpl(const string& buffer, const string::size_type position,
|
|
const string::size_type end, string::size_type* newPosition)
|
|
{
|
|
const string::value_type* const pend = buffer.data() + end;
|
|
@@ -588,7 +588,7 @@ void datetime::parse(const string& buffer, const string::size_type position,
|
|
}
|
|
|
|
|
|
-void datetime::generate(utility::outputStream& os, const string::size_type /* maxLineLength */,
|
|
+void datetime::generateImpl(utility::outputStream& os, const string::size_type /* maxLineLength */,
|
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
{
|
|
static const string::value_type* dayNames[] =
|
|
@@ -784,9 +784,9 @@ ref <component> datetime::clone() const
|
|
}
|
|
|
|
|
|
-const std::vector <ref <const component> > datetime::getChildComponents() const
|
|
+const std::vector <ref <component> > datetime::getChildComponents()
|
|
{
|
|
- return std::vector <ref <const component> >();
|
|
+ return std::vector <ref <component> >();
|
|
}
|
|
|
|
|
|
diff --git a/src/disposition.cpp b/src/disposition.cpp
|
|
index b8059a7..24a4579 100644
|
|
--- a/src/disposition.cpp
|
|
+++ b/src/disposition.cpp
|
|
@@ -79,9 +79,9 @@ disposition& disposition::operator=(const disposition& other)
|
|
}
|
|
|
|
|
|
-const std::vector <ref <const component> > disposition::getChildComponents() const
|
|
+const std::vector <ref <component> > disposition::getChildComponents()
|
|
{
|
|
- return std::vector <ref <const component> >();
|
|
+ return std::vector <ref <component> >();
|
|
}
|
|
|
|
|
|
@@ -171,7 +171,7 @@ const std::vector <string> disposition::getModifierList() const
|
|
}
|
|
|
|
|
|
-void disposition::parse(const string& buffer, const string::size_type position,
|
|
+void disposition::parseImpl(const string& buffer, const string::size_type position,
|
|
const string::size_type end, string::size_type* newPosition)
|
|
{
|
|
// disposition-mode ";" disposition-type
|
|
@@ -276,7 +276,7 @@ void disposition::parse(const string& buffer, const string::size_type position,
|
|
}
|
|
|
|
|
|
-void disposition::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
+void disposition::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
{
|
|
string::size_type pos = curLinePos;
|
|
diff --git a/src/encoding.cpp b/src/encoding.cpp
|
|
index 5d99ab6..343a822 100644
|
|
--- a/src/encoding.cpp
|
|
+++ b/src/encoding.cpp
|
|
@@ -61,7 +61,7 @@ encoding::encoding(const encoding& enc)
|
|
}
|
|
|
|
|
|
-void encoding::parse(const string& buffer, const string::size_type position,
|
|
+void encoding::parseImpl(const string& buffer, const string::size_type position,
|
|
const string::size_type end, string::size_type* newPosition)
|
|
{
|
|
m_usage = USAGE_UNKNOWN;
|
|
@@ -80,7 +80,7 @@ void encoding::parse(const string& buffer, const string::size_type position,
|
|
}
|
|
|
|
|
|
-void encoding::generate(utility::outputStream& os, const string::size_type /* maxLineLength */,
|
|
+void encoding::generateImpl(utility::outputStream& os, const string::size_type /* maxLineLength */,
|
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
{
|
|
os << m_name;
|
|
@@ -268,9 +268,9 @@ void encoding::setUsage(const EncodingUsage usage)
|
|
}
|
|
|
|
|
|
-const std::vector <ref <const component> > encoding::getChildComponents() const
|
|
+const std::vector <ref <component> > encoding::getChildComponents()
|
|
{
|
|
- return std::vector <ref <const component> >();
|
|
+ return std::vector <ref <component> >();
|
|
}
|
|
|
|
|
|
diff --git a/src/header.cpp b/src/header.cpp
|
|
index 443aab8..fcdca2c 100644
|
|
--- a/src/header.cpp
|
|
+++ b/src/header.cpp
|
|
@@ -61,7 +61,7 @@ field-body-contents =
|
|
specials tokens, or else consisting of texts>
|
|
*/
|
|
|
|
-void header::parse(const string& buffer, const string::size_type position,
|
|
+void header::parseImpl(const string& buffer, const string::size_type position,
|
|
const string::size_type end, string::size_type* newPosition)
|
|
{
|
|
string::size_type pos = position;
|
|
@@ -83,7 +83,7 @@ void header::parse(const string& buffer, const string::size_type position,
|
|
}
|
|
|
|
|
|
-void header::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
+void header::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
|
const string::size_type /* curLinePos */, string::size_type* newLinePos) const
|
|
{
|
|
// Generate the fields
|
|
@@ -337,9 +337,9 @@ const std::vector <ref <headerField> > header::getFieldList()
|
|
}
|
|
|
|
|
|
-const std::vector <ref <const component> > header::getChildComponents() const
|
|
+const std::vector <ref <component> > header::getChildComponents()
|
|
{
|
|
- std::vector <ref <const component> > list;
|
|
+ std::vector <ref <component> > list;
|
|
|
|
copy_vector(m_fields, list);
|
|
|
|
diff --git a/src/headerField.cpp b/src/headerField.cpp
|
|
index d1d4236..a8460aa 100644
|
|
--- a/src/headerField.cpp
|
|
+++ b/src/headerField.cpp
|
|
@@ -262,14 +262,14 @@ ref <headerField> headerField::parseNext(const string& buffer, const string::siz
|
|
}
|
|
|
|
|
|
-void headerField::parse(const string& buffer, const string::size_type position, const string::size_type end,
|
|
+void headerField::parseImpl(const string& buffer, const string::size_type position, const string::size_type end,
|
|
string::size_type* newPosition)
|
|
{
|
|
m_value->parse(buffer, position, end, newPosition);
|
|
}
|
|
|
|
|
|
-void headerField::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
+void headerField::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
{
|
|
os << m_name + ": ";
|
|
@@ -296,9 +296,9 @@ bool headerField::isCustom() const
|
|
}
|
|
|
|
|
|
-const std::vector <ref <const component> > headerField::getChildComponents() const
|
|
+const std::vector <ref <component> > headerField::getChildComponents()
|
|
{
|
|
- std::vector <ref <const component> > list;
|
|
+ std::vector <ref <component> > list;
|
|
|
|
if (m_value)
|
|
list.push_back(m_value);
|
|
diff --git a/src/mailbox.cpp b/src/mailbox.cpp
|
|
index fea7479..dfdccad 100644
|
|
--- a/src/mailbox.cpp
|
|
+++ b/src/mailbox.cpp
|
|
@@ -65,7 +65,7 @@ angle-addr = [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr
|
|
|
|
*/
|
|
|
|
-void mailbox::parse(const string& buffer, const string::size_type position,
|
|
+void mailbox::parseImpl(const string& buffer, const string::size_type position,
|
|
const string::size_type end, string::size_type* newPosition)
|
|
{
|
|
const string::value_type* const pend = buffer.data() + end;
|
|
@@ -343,7 +343,7 @@ void mailbox::parse(const string& buffer, const string::size_type position,
|
|
}
|
|
|
|
|
|
-void mailbox::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
+void mailbox::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
{
|
|
if (m_name.isEmpty())
|
|
@@ -514,9 +514,9 @@ void mailbox::setEmail(const string& email)
|
|
}
|
|
|
|
|
|
-const std::vector <ref <const component> > mailbox::getChildComponents() const
|
|
+const std::vector <ref <component> > mailbox::getChildComponents()
|
|
{
|
|
- return std::vector <ref <const component> >();
|
|
+ return std::vector <ref <component> >();
|
|
}
|
|
|
|
|
|
diff --git a/src/mailboxGroup.cpp b/src/mailboxGroup.cpp
|
|
index 94f7ba6..c37444a 100644
|
|
--- a/src/mailboxGroup.cpp
|
|
+++ b/src/mailboxGroup.cpp
|
|
@@ -54,7 +54,7 @@ mailboxGroup::~mailboxGroup()
|
|
}
|
|
|
|
|
|
-void mailboxGroup::parse(const string& buffer, const string::size_type position,
|
|
+void mailboxGroup::parseImpl(const string& buffer, const string::size_type position,
|
|
const string::size_type end, string::size_type* newPosition)
|
|
{
|
|
const string::value_type* const pend = buffer.data() + end;
|
|
@@ -111,7 +111,7 @@ void mailboxGroup::parse(const string& buffer, const string::size_type position,
|
|
}
|
|
|
|
|
|
-void mailboxGroup::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
+void mailboxGroup::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
{
|
|
// We have to encode the name:
|
|
@@ -348,9 +348,9 @@ const std::vector <ref <mailbox> > mailboxGroup::getMailboxList()
|
|
}
|
|
|
|
|
|
-const std::vector <ref <const component> > mailboxGroup::getChildComponents() const
|
|
+const std::vector <ref <component> > mailboxGroup::getChildComponents()
|
|
{
|
|
- std::vector <ref <const component> > list;
|
|
+ std::vector <ref <component> > list;
|
|
|
|
copy_vector(m_list, list);
|
|
|
|
diff --git a/src/mailboxList.cpp b/src/mailboxList.cpp
|
|
index 0023d9d..f87fb48 100644
|
|
--- a/src/mailboxList.cpp
|
|
+++ b/src/mailboxList.cpp
|
|
@@ -190,20 +190,20 @@ mailboxList& mailboxList::operator=(const mailboxList& other)
|
|
}
|
|
|
|
|
|
-const std::vector <ref <const component> > mailboxList::getChildComponents() const
|
|
+const std::vector <ref <component> > mailboxList::getChildComponents()
|
|
{
|
|
return (m_list.getChildComponents());
|
|
}
|
|
|
|
|
|
-void mailboxList::parse(const string& buffer, const string::size_type position,
|
|
+void mailboxList::parseImpl(const string& buffer, const string::size_type position,
|
|
const string::size_type end, string::size_type* newPosition)
|
|
{
|
|
m_list.parse(buffer, position, end, newPosition);
|
|
}
|
|
|
|
|
|
-void mailboxList::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
+void mailboxList::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
{
|
|
m_list.generate(os, maxLineLength, curLinePos, newLinePos);
|
|
diff --git a/src/mediaType.cpp b/src/mediaType.cpp
|
|
index 725f933..627b276 100644
|
|
--- a/src/mediaType.cpp
|
|
+++ b/src/mediaType.cpp
|
|
@@ -48,7 +48,7 @@ mediaType::mediaType(const string& type, const string& subType)
|
|
}
|
|
|
|
|
|
-void mediaType::parse(const string& buffer, const string::size_type position,
|
|
+void mediaType::parseImpl(const string& buffer, const string::size_type position,
|
|
const string::size_type end, string::size_type* newPosition)
|
|
{
|
|
const string::value_type* const pend = buffer.data() + end;
|
|
@@ -82,7 +82,7 @@ void mediaType::parse(const string& buffer, const string::size_type position,
|
|
}
|
|
|
|
|
|
-void mediaType::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
+void mediaType::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
{
|
|
const string value = m_type + "/" + m_subType;
|
|
@@ -176,9 +176,9 @@ void mediaType::setFromString(const string& type)
|
|
}
|
|
|
|
|
|
-const std::vector <ref <const component> > mediaType::getChildComponents() const
|
|
+const std::vector <ref <component> > mediaType::getChildComponents()
|
|
{
|
|
- return std::vector <ref <const component> >();
|
|
+ return std::vector <ref <component> >();
|
|
}
|
|
|
|
|
|
diff --git a/src/message.cpp b/src/message.cpp
|
|
index 1b4f086..3fa9b6a 100644
|
|
--- a/src/message.cpp
|
|
+++ b/src/message.cpp
|
|
@@ -61,9 +61,14 @@ const string message::generate(const string::size_type maxLineLength,
|
|
}
|
|
|
|
|
|
-void message::parse(const string& buffer)
|
|
+
|
|
+void message::generate
|
|
+ (ref <utility::outputStream> os,
|
|
+ const string::size_type maxLineLength,
|
|
+ const string::size_type curLinePos,
|
|
+ string::size_type* newLinePos) const
|
|
{
|
|
- bodyPart::parse(buffer);
|
|
+ bodyPart::generate(os, maxLineLength, curLinePos, newLinePos);
|
|
}
|
|
|
|
|
|
diff --git a/src/messageId.cpp b/src/messageId.cpp
|
|
index 961fb63..1f4b186 100644
|
|
--- a/src/messageId.cpp
|
|
+++ b/src/messageId.cpp
|
|
@@ -61,7 +61,7 @@ messageId::messageId(const string& left, const string& right)
|
|
msg-id = [CFWS] "<" id-left "@" id-right ">" [CFWS]
|
|
*/
|
|
|
|
-void messageId::parse(const string& buffer, const string::size_type position,
|
|
+void messageId::parseImpl(const string& buffer, const string::size_type position,
|
|
const string::size_type end, string::size_type* newPosition)
|
|
{
|
|
const string::value_type* const pend = buffer.data() + end;
|
|
@@ -185,7 +185,7 @@ const string messageId::getId() const
|
|
}
|
|
|
|
|
|
-void messageId::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
+void messageId::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
{
|
|
string::size_type pos = curLinePos;
|
|
@@ -288,9 +288,9 @@ void messageId::setRight(const string& right)
|
|
}
|
|
|
|
|
|
-const std::vector <ref <const component> > messageId::getChildComponents() const
|
|
+const std::vector <ref <component> > messageId::getChildComponents()
|
|
{
|
|
- return std::vector <ref <const component> >();
|
|
+ return std::vector <ref <component> >();
|
|
}
|
|
|
|
|
|
diff --git a/src/messageIdSequence.cpp b/src/messageIdSequence.cpp
|
|
index 08103d0..0a5c9a0 100644
|
|
--- a/src/messageIdSequence.cpp
|
|
+++ b/src/messageIdSequence.cpp
|
|
@@ -74,9 +74,9 @@ messageIdSequence& messageIdSequence::operator=(const messageIdSequence& other)
|
|
}
|
|
|
|
|
|
-const std::vector <ref <const component> > messageIdSequence::getChildComponents() const
|
|
+const std::vector <ref <component> > messageIdSequence::getChildComponents()
|
|
{
|
|
- std::vector <ref <const component> > res;
|
|
+ std::vector <ref <component> > res;
|
|
|
|
copy_vector(m_list, res);
|
|
|
|
@@ -84,7 +84,7 @@ const std::vector <ref <const component> > messageIdSequence::getChildComponents
|
|
}
|
|
|
|
|
|
-void messageIdSequence::parse(const string& buffer, const string::size_type position,
|
|
+void messageIdSequence::parseImpl(const string& buffer, const string::size_type position,
|
|
const string::size_type end, string::size_type* newPosition)
|
|
{
|
|
removeAllMessageIds();
|
|
@@ -106,7 +106,7 @@ void messageIdSequence::parse(const string& buffer, const string::size_type posi
|
|
}
|
|
|
|
|
|
-void messageIdSequence::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
+void messageIdSequence::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
{
|
|
string::size_type pos = curLinePos;
|
|
diff --git a/src/parameter.cpp b/src/parameter.cpp
|
|
index ccbe1a5..58d9a3e 100644
|
|
--- a/src/parameter.cpp
|
|
+++ b/src/parameter.cpp
|
|
@@ -36,19 +36,19 @@ namespace vmime
|
|
|
|
|
|
parameter::parameter(const string& name)
|
|
- : m_name(name)
|
|
+ : m_name(name), m_value(vmime::create <word>())
|
|
{
|
|
}
|
|
|
|
|
|
parameter::parameter(const string& name, const word& value)
|
|
- : m_name(name), m_value(value)
|
|
+ : m_name(name), m_value(vmime::create <word>(value))
|
|
{
|
|
}
|
|
|
|
|
|
parameter::parameter(const string& name, const string& value)
|
|
- : m_name(name), m_value(value)
|
|
+ : m_name(name), m_value(vmime::create <word>(value))
|
|
{
|
|
}
|
|
|
|
@@ -73,7 +73,7 @@ void parameter::copyFrom(const component& other)
|
|
const parameter& param = dynamic_cast <const parameter&>(other);
|
|
|
|
m_name = param.m_name;
|
|
- m_value.copyFrom(param.m_value);
|
|
+ m_value->copyFrom(*param.m_value);
|
|
}
|
|
|
|
|
|
@@ -92,7 +92,7 @@ const string& parameter::getName() const
|
|
|
|
const word& parameter::getValue() const
|
|
{
|
|
- return m_value;
|
|
+ return *m_value;
|
|
}
|
|
|
|
|
|
@@ -109,15 +109,15 @@ void parameter::setValue(const component& value)
|
|
|
|
void parameter::setValue(const word& value)
|
|
{
|
|
- m_value = value;
|
|
+ *m_value = value;
|
|
}
|
|
|
|
|
|
-void parameter::parse(const string& buffer, const string::size_type position,
|
|
+void parameter::parseImpl(const string& buffer, const string::size_type position,
|
|
const string::size_type end, string::size_type* newPosition)
|
|
{
|
|
- m_value.setBuffer(string(buffer.begin() + position, buffer.begin() + end));
|
|
- m_value.setCharset(charset(charsets::US_ASCII));
|
|
+ m_value->setBuffer(string(buffer.begin() + position, buffer.begin() + end));
|
|
+ m_value->setCharset(charset(charsets::US_ASCII));
|
|
|
|
if (newPosition)
|
|
*newPosition = end;
|
|
@@ -248,16 +248,16 @@ void parameter::parse(const std::vector <valueChunk>& chunks)
|
|
}
|
|
}
|
|
|
|
- m_value.setBuffer(value.str());
|
|
- m_value.setCharset(ch);
|
|
+ m_value->setBuffer(value.str());
|
|
+ m_value->setCharset(ch);
|
|
}
|
|
|
|
|
|
-void parameter::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
+void parameter::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
{
|
|
const string& name = m_name;
|
|
- const string& value = m_value.getBuffer();
|
|
+ const string& value = m_value->getBuffer();
|
|
|
|
// For compatibility with implementations that do not understand RFC-2231,
|
|
// also generate a normal "7bit/us-ascii" parameter
|
|
@@ -344,7 +344,7 @@ void parameter::generate(utility::outputStream& os, const string::size_type maxL
|
|
// 7-bit (ASCII) bytes in the input will be used to determine if
|
|
// we need to encode the whole buffer.
|
|
encoding recommendedEnc;
|
|
- const bool alwaysEncode = m_value.getCharset().getRecommendedEncoding(recommendedEnc);
|
|
+ const bool alwaysEncode = m_value->getCharset().getRecommendedEncoding(recommendedEnc);
|
|
bool extended = alwaysEncode;
|
|
|
|
if (needQuotedPrintable)
|
|
@@ -352,7 +352,7 @@ void parameter::generate(utility::outputStream& os, const string::size_type maxL
|
|
// Send the name in quoted-printable, so outlook express et.al.
|
|
// will understand the real filename
|
|
size_t oldLen = sevenBitBuffer.length();
|
|
- m_value.generate(sevenBitStream);
|
|
+ m_value->generate(sevenBitStream);
|
|
pos += sevenBitBuffer.length() - oldLen;
|
|
extended = true; // also send with RFC-2231 encoding
|
|
}
|
|
@@ -429,7 +429,7 @@ void parameter::generate(utility::outputStream& os, const string::size_type maxL
|
|
// + at least 5 characters for the value
|
|
const string::size_type firstSectionLength =
|
|
name.length() + 4 /* *0*= */ + 2 /* '' */
|
|
- + m_value.getCharset().getName().length();
|
|
+ + m_value->getCharset().getName().length();
|
|
|
|
if (pos + firstSectionLength + 5 >= maxLineLength)
|
|
{
|
|
@@ -539,7 +539,7 @@ void parameter::generate(utility::outputStream& os, const string::size_type maxL
|
|
|
|
if (sectionNumber == 0)
|
|
{
|
|
- os << m_value.getCharset().getName();
|
|
+ os << m_value->getCharset().getName();
|
|
os << '\'' << /* No language */ '\'';
|
|
}
|
|
|
|
@@ -570,11 +570,11 @@ void parameter::generate(utility::outputStream& os, const string::size_type maxL
|
|
}
|
|
|
|
|
|
-const std::vector <ref <const component> > parameter::getChildComponents() const
|
|
+const std::vector <ref <component> > parameter::getChildComponents()
|
|
{
|
|
- std::vector <ref <const component> > list;
|
|
+ std::vector <ref <component> > list;
|
|
|
|
- list.push_back(ref <const component>::fromPtr(&m_value));
|
|
+ list.push_back(m_value);
|
|
|
|
return list;
|
|
}
|
|
diff --git a/src/parameterizedHeaderField.cpp b/src/parameterizedHeaderField.cpp
|
|
index 464990e..756d02f 100644
|
|
--- a/src/parameterizedHeaderField.cpp
|
|
+++ b/src/parameterizedHeaderField.cpp
|
|
@@ -78,7 +78,7 @@ struct paramInfo
|
|
#endif // VMIME_BUILDING_DOC
|
|
|
|
|
|
-void parameterizedHeaderField::parse(const string& buffer, const string::size_type position,
|
|
+void parameterizedHeaderField::parseImpl(const string& buffer, const string::size_type position,
|
|
const string::size_type end, string::size_type* newPosition)
|
|
{
|
|
const string::value_type* const pend = buffer.data() + end;
|
|
@@ -328,13 +328,13 @@ void parameterizedHeaderField::parse(const string& buffer, const string::size_ty
|
|
}
|
|
|
|
|
|
-void parameterizedHeaderField::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
+void parameterizedHeaderField::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
{
|
|
string::size_type pos = curLinePos;
|
|
|
|
// Parent header field
|
|
- headerField::generate(os, maxLineLength, pos, &pos);
|
|
+ headerField::generateImpl(os, maxLineLength, pos, &pos);
|
|
|
|
// Parameters
|
|
for (std::vector <ref <parameter> >::const_iterator
|
|
@@ -552,11 +552,11 @@ const std::vector <ref <parameter> > parameterizedHeaderField::getParameterList(
|
|
}
|
|
|
|
|
|
-const std::vector <ref <const component> > parameterizedHeaderField::getChildComponents() const
|
|
+const std::vector <ref <component> > parameterizedHeaderField::getChildComponents()
|
|
{
|
|
- std::vector <ref <const component> > list = headerField::getChildComponents();
|
|
+ std::vector <ref <component> > list = headerField::getChildComponents();
|
|
|
|
- for (std::vector <ref <parameter> >::const_iterator it = m_params.begin() ;
|
|
+ for (std::vector <ref <parameter> >::iterator it = m_params.begin() ;
|
|
it != m_params.end() ; ++it)
|
|
{
|
|
list.push_back(*it);
|
|
diff --git a/src/path.cpp b/src/path.cpp
|
|
index 37a4090..d92bb0a 100644
|
|
--- a/src/path.cpp
|
|
+++ b/src/path.cpp
|
|
@@ -106,14 +106,14 @@ path& path::operator=(const path& other)
|
|
}
|
|
|
|
|
|
-const std::vector <ref <const component> > path::getChildComponents() const
|
|
+const std::vector <ref <component> > path::getChildComponents()
|
|
{
|
|
- return std::vector <ref <const component> >();
|
|
+ return std::vector <ref <component> >();
|
|
}
|
|
|
|
|
|
-void path::parse(const string& buffer, const string::size_type position,
|
|
- const string::size_type end, string::size_type* newPosition)
|
|
+void path::parseImpl(const string& buffer, const string::size_type position,
|
|
+ const string::size_type end, string::size_type* newPosition)
|
|
{
|
|
string::size_type pos = position;
|
|
|
|
@@ -165,8 +165,8 @@ void path::parse(const string& buffer, const string::size_type position,
|
|
}
|
|
|
|
|
|
-void path::generate(utility::outputStream& os, const string::size_type /* maxLineLength */,
|
|
- const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
+void path::generateImpl(utility::outputStream& os, const string::size_type /* maxLineLength */,
|
|
+ const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
{
|
|
if (m_localPart.empty() && m_domain.empty())
|
|
{
|
|
diff --git a/src/platforms/posix/posixFile.cpp b/src/platforms/posix/posixFile.cpp
|
|
index ec529eb..4087a21 100644
|
|
--- a/src/platforms/posix/posixFile.cpp
|
|
+++ b/src/platforms/posix/posixFile.cpp
|
|
@@ -224,6 +224,26 @@ vmime::utility::stream::size_type posixFileReaderInputStream::skip(const size_ty
|
|
}
|
|
|
|
|
|
+vmime::utility::stream::size_type posixFileReaderInputStream::getPosition() const
|
|
+{
|
|
+ const off_t curPos = ::lseek(m_fd, 0, SEEK_CUR);
|
|
+
|
|
+ if (curPos == off_t(-1))
|
|
+ posixFileSystemFactory::reportError(m_path, errno);
|
|
+
|
|
+ return static_cast <size_type>(curPos);
|
|
+}
|
|
+
|
|
+
|
|
+void posixFileReaderInputStream::seek(const size_type pos)
|
|
+{
|
|
+ const off_t newPos = ::lseek(m_fd, pos, SEEK_SET);
|
|
+
|
|
+ if (newPos == off_t(-1))
|
|
+ posixFileSystemFactory::reportError(m_path, errno);
|
|
+}
|
|
+
|
|
+
|
|
|
|
//
|
|
// posixFileWriter
|
|
diff --git a/src/platforms/windows/windowsFile.cpp b/src/platforms/windows/windowsFile.cpp
|
|
index 624612a..5da786e 100644
|
|
--- a/src/platforms/windows/windowsFile.cpp
|
|
+++ b/src/platforms/windows/windowsFile.cpp
|
|
@@ -479,6 +479,24 @@ vmime::utility::stream::size_type windowsFileReaderInputStream::skip(const size_
|
|
return (dwNewPos - dwCurPos);
|
|
}
|
|
|
|
+vmime::utility::stream::size_type windowsFileReaderInputStream::getPosition() const
|
|
+{
|
|
+ DWORD dwCurPos = SetFilePointer(m_hFile, 0, NULL, FILE_CURRENT);
|
|
+
|
|
+ if (dwCurPos == INVALID_SET_FILE_POINTER)
|
|
+ windowsFileSystemFactory::reportError(m_path, GetLastError());
|
|
+
|
|
+ return static_cast <size_type>(dwCurPos);
|
|
+}
|
|
+
|
|
+void windowsFileReaderInputStream::seek(const size_type pos)
|
|
+{
|
|
+ DWORD dwNewPos = SetFilePointer(m_hFile, (LONG)pos, NULL, FILE_BEGIN);
|
|
+
|
|
+ if (dwNewPos == INVALID_SET_FILE_POINTER)
|
|
+ windowsFileSystemFactory::reportError(m_path, GetLastError());
|
|
+}
|
|
+
|
|
windowsFileWriter::windowsFileWriter(const vmime::utility::file::path& path, const vmime::string& nativePath)
|
|
: m_path(path), m_nativePath(nativePath)
|
|
{
|
|
diff --git a/src/relay.cpp b/src/relay.cpp
|
|
index 5cd454f..97f793d 100644
|
|
--- a/src/relay.cpp
|
|
+++ b/src/relay.cpp
|
|
@@ -57,7 +57,7 @@ relay::relay(const relay& r)
|
|
["for" addr-spec] ; initial form
|
|
*/
|
|
|
|
-void relay::parse(const string& buffer, const string::size_type position,
|
|
+void relay::parseImpl(const string& buffer, const string::size_type position,
|
|
const string::size_type end, string::size_type* newPosition)
|
|
{
|
|
const string::value_type* const pend = buffer.data() + end;
|
|
@@ -198,7 +198,7 @@ void relay::parse(const string& buffer, const string::size_type position,
|
|
}
|
|
|
|
|
|
-void relay::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
+void relay::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
{
|
|
std::ostringstream oss;
|
|
@@ -338,10 +338,10 @@ std::vector <string>& relay::getWithList()
|
|
}
|
|
|
|
|
|
-const std::vector <ref <const component> > relay::getChildComponents() const
|
|
+const std::vector <ref <component> > relay::getChildComponents()
|
|
{
|
|
// TODO: should fields inherit from 'component'? (using typeAdapter)
|
|
- return std::vector <ref <const component> >();
|
|
+ return std::vector <ref <component> >();
|
|
}
|
|
|
|
|
|
diff --git a/src/streamContentHandler.cpp b/src/streamContentHandler.cpp
|
|
index 89a36b4..14837d2 100644
|
|
--- a/src/streamContentHandler.cpp
|
|
+++ b/src/streamContentHandler.cpp
|
|
@@ -25,6 +25,7 @@
|
|
|
|
#include "vmime/utility/outputStreamAdapter.hpp"
|
|
#include "vmime/utility/inputStreamStringAdapter.hpp"
|
|
+#include "vmime/utility/seekableInputStream.hpp"
|
|
#include "vmime/utility/streamUtils.hpp"
|
|
|
|
|
|
@@ -207,6 +208,9 @@ const vmime::encoding& streamContentHandler::getEncoding() const
|
|
|
|
bool streamContentHandler::isBuffered() const
|
|
{
|
|
+ if (m_stream.dynamicCast <utility::seekableInputStream>() != NULL)
|
|
+ return true;
|
|
+
|
|
// FIXME: some streams can be resetted
|
|
return false;
|
|
}
|
|
diff --git a/src/text.cpp b/src/text.cpp
|
|
index 66c3b35..91b81e1 100644
|
|
--- a/src/text.cpp
|
|
+++ b/src/text.cpp
|
|
@@ -67,7 +67,7 @@ text::~text()
|
|
}
|
|
|
|
|
|
-void text::parse(const string& buffer, const string::size_type position,
|
|
+void text::parseImpl(const string& buffer, const string::size_type position,
|
|
const string::size_type end, string::size_type* newPosition)
|
|
{
|
|
removeAllWords();
|
|
@@ -85,7 +85,7 @@ void text::parse(const string& buffer, const string::size_type position,
|
|
}
|
|
|
|
|
|
-void text::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
+void text::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
{
|
|
encodeAndFold(os, maxLineLength, curLinePos, newLinePos, 0);
|
|
@@ -389,9 +389,9 @@ text* text::decodeAndUnfold(const string& in, text* generateInExisting)
|
|
}
|
|
|
|
|
|
-const std::vector <ref <const component> > text::getChildComponents() const
|
|
+const std::vector <ref <component> > text::getChildComponents()
|
|
{
|
|
- std::vector <ref <const component> > list;
|
|
+ std::vector <ref <component> > list;
|
|
|
|
copy_vector(m_words, list);
|
|
|
|
diff --git a/src/utility/inputStreamAdapter.cpp b/src/utility/inputStreamAdapter.cpp
|
|
index b44b084..441307b 100644
|
|
--- a/src/utility/inputStreamAdapter.cpp
|
|
+++ b/src/utility/inputStreamAdapter.cpp
|
|
@@ -65,6 +65,18 @@ stream::size_type inputStreamAdapter::skip(const size_type count)
|
|
}
|
|
|
|
|
|
+stream::size_type inputStreamAdapter::getPosition() const
|
|
+{
|
|
+ return m_stream.tellg();
|
|
+}
|
|
+
|
|
+
|
|
+void inputStreamAdapter::seek(const size_type pos)
|
|
+{
|
|
+ m_stream.seekg(pos, std::ios_base::beg);
|
|
+}
|
|
+
|
|
+
|
|
} // utility
|
|
} // vmime
|
|
|
|
diff --git a/src/utility/inputStreamByteBufferAdapter.cpp b/src/utility/inputStreamByteBufferAdapter.cpp
|
|
index 92e779f..907f1ee 100644
|
|
--- a/src/utility/inputStreamByteBufferAdapter.cpp
|
|
+++ b/src/utility/inputStreamByteBufferAdapter.cpp
|
|
@@ -85,6 +85,19 @@ stream::size_type inputStreamByteBufferAdapter::skip(const size_type count)
|
|
}
|
|
|
|
|
|
+stream::size_type inputStreamByteBufferAdapter::getPosition() const
|
|
+{
|
|
+ return m_pos;
|
|
+}
|
|
+
|
|
+
|
|
+void inputStreamByteBufferAdapter::seek(const size_type pos)
|
|
+{
|
|
+ if (pos <= m_length)
|
|
+ m_pos = pos;
|
|
+}
|
|
+
|
|
+
|
|
} // utility
|
|
} // vmime
|
|
|
|
diff --git a/src/utility/inputStreamStringAdapter.cpp b/src/utility/inputStreamStringAdapter.cpp
|
|
index 31c9fda..9b8fb0c 100644
|
|
--- a/src/utility/inputStreamStringAdapter.cpp
|
|
+++ b/src/utility/inputStreamStringAdapter.cpp
|
|
@@ -89,6 +89,19 @@ stream::size_type inputStreamStringAdapter::skip(const size_type count)
|
|
}
|
|
|
|
|
|
+stream::size_type inputStreamStringAdapter::getPosition() const
|
|
+{
|
|
+ return m_pos - m_begin;
|
|
+}
|
|
+
|
|
+
|
|
+void inputStreamStringAdapter::seek(const size_type pos)
|
|
+{
|
|
+ if (m_begin + pos <= m_end)
|
|
+ m_pos = m_begin + pos;
|
|
+}
|
|
+
|
|
+
|
|
} // utility
|
|
} // vmime
|
|
|
|
diff --git a/src/utility/inputStreamStringProxyAdapter.cpp b/src/utility/inputStreamStringProxyAdapter.cpp
|
|
index 5e4b60b..feecddd 100644
|
|
--- a/src/utility/inputStreamStringProxyAdapter.cpp
|
|
+++ b/src/utility/inputStreamStringProxyAdapter.cpp
|
|
@@ -84,6 +84,19 @@ stream::size_type inputStreamStringProxyAdapter::skip(const size_type count)
|
|
}
|
|
|
|
|
|
+stream::size_type inputStreamStringProxyAdapter::getPosition() const
|
|
+{
|
|
+ return m_pos;
|
|
+}
|
|
+
|
|
+
|
|
+void inputStreamStringProxyAdapter::seek(const size_type pos)
|
|
+{
|
|
+ if (pos <= m_buffer.length())
|
|
+ m_pos = pos;
|
|
+}
|
|
+
|
|
+
|
|
} // utility
|
|
} // vmime
|
|
|
|
diff --git a/src/utility/parserInputStreamAdapter.cpp b/src/utility/parserInputStreamAdapter.cpp
|
|
new file mode 100644
|
|
index 0000000..7a38ef1
|
|
--- /dev/null
|
|
+++ b/src/utility/parserInputStreamAdapter.cpp
|
|
@@ -0,0 +1,162 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#include "vmime/utility/parserInputStreamAdapter.hpp"
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+parserInputStreamAdapter::parserInputStreamAdapter(ref <seekableInputStream> stream)
|
|
+ : m_stream(stream)
|
|
+{
|
|
+}
|
|
+
|
|
+
|
|
+bool parserInputStreamAdapter::eof() const
|
|
+{
|
|
+ return m_stream->eof();
|
|
+}
|
|
+
|
|
+
|
|
+void parserInputStreamAdapter::reset()
|
|
+{
|
|
+ m_stream->reset();
|
|
+}
|
|
+
|
|
+
|
|
+stream::size_type parserInputStreamAdapter::read
|
|
+ (value_type* const data, const size_type count)
|
|
+{
|
|
+ return m_stream->read(data, count);
|
|
+}
|
|
+
|
|
+
|
|
+ref <seekableInputStream> parserInputStreamAdapter::getUnderlyingStream()
|
|
+{
|
|
+ return m_stream;
|
|
+}
|
|
+
|
|
+
|
|
+const string parserInputStreamAdapter::extract(const size_type begin, const size_type end) const
|
|
+{
|
|
+ const size_type initialPos = m_stream->getPosition();
|
|
+
|
|
+ try
|
|
+ {
|
|
+ value_type *buffer = new value_type[end - begin + 1];
|
|
+
|
|
+ m_stream->seek(begin);
|
|
+
|
|
+ const size_type readBytes = m_stream->read(buffer, end - begin);
|
|
+ buffer[readBytes] = '\0';
|
|
+
|
|
+ m_stream->seek(initialPos);
|
|
+
|
|
+ string str(buffer, buffer + readBytes);
|
|
+ delete [] buffer;
|
|
+
|
|
+ return str;
|
|
+ }
|
|
+ catch (...)
|
|
+ {
|
|
+ m_stream->seek(initialPos);
|
|
+ throw;
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+stream::size_type parserInputStreamAdapter::findNext
|
|
+ (const std::string& token, const size_type startPosition)
|
|
+{
|
|
+ static const unsigned int BUFFER_SIZE = 4096;
|
|
+
|
|
+ // Token must not be longer than BUFFER_SIZE/2
|
|
+ if (token.empty() || token.length() > BUFFER_SIZE / 2)
|
|
+ return npos;
|
|
+
|
|
+ const size_type initialPos = getPosition();
|
|
+
|
|
+ seek(startPosition);
|
|
+
|
|
+ try
|
|
+ {
|
|
+ value_type findBuffer[BUFFER_SIZE];
|
|
+ value_type* findBuffer1 = findBuffer;
|
|
+ value_type* findBuffer2 = findBuffer + (BUFFER_SIZE / 2) * sizeof(value_type);
|
|
+
|
|
+ size_type findBufferLen = 0;
|
|
+ size_type findBufferOffset = 0;
|
|
+
|
|
+ // Fill in initial buffer
|
|
+ findBufferLen = read(findBuffer, BUFFER_SIZE * sizeof(value_type));
|
|
+
|
|
+ for (;;)
|
|
+ {
|
|
+ // Find token
|
|
+ for (value_type *begin = findBuffer, *end = findBuffer + findBufferLen - token.length() ;
|
|
+ begin <= end ; ++begin)
|
|
+ {
|
|
+ if (begin[0] == token[0] &&
|
|
+ (token.length() == 1 ||
|
|
+ memcmp(static_cast <const void *>(&begin[1]),
|
|
+ static_cast <const void *>(token.data() + 1),
|
|
+ token.length() - 1) == 0))
|
|
+ {
|
|
+ seek(initialPos);
|
|
+ return startPosition + findBufferOffset + (begin - findBuffer);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // Rotate buffer
|
|
+ memcpy(findBuffer1, findBuffer2, (BUFFER_SIZE / 2) * sizeof(value_type));
|
|
+
|
|
+ // Read more bytes
|
|
+ if (findBufferLen < BUFFER_SIZE && eof())
|
|
+ {
|
|
+ break;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ const size_type bytesRead = read(findBuffer2, (BUFFER_SIZE / 2) * sizeof(value_type));
|
|
+ findBufferLen = (BUFFER_SIZE / 2) + bytesRead;
|
|
+ findBufferOffset += (BUFFER_SIZE / 2);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ seek(initialPos);
|
|
+ }
|
|
+ catch (...)
|
|
+ {
|
|
+ seek(initialPos);
|
|
+ throw;
|
|
+ }
|
|
+
|
|
+ return npos;
|
|
+}
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
diff --git a/src/utility/seekableInputStreamRegionAdapter.cpp b/src/utility/seekableInputStreamRegionAdapter.cpp
|
|
new file mode 100644
|
|
index 0000000..348618c
|
|
--- /dev/null
|
|
+++ b/src/utility/seekableInputStreamRegionAdapter.cpp
|
|
@@ -0,0 +1,95 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#include "vmime/utility/seekableInputStreamRegionAdapter.hpp"
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+seekableInputStreamRegionAdapter::seekableInputStreamRegionAdapter
|
|
+ (ref <seekableInputStream> stream, const size_type begin, const size_type length)
|
|
+ : m_stream(stream), m_begin(begin), m_length(length)
|
|
+{
|
|
+}
|
|
+
|
|
+
|
|
+bool seekableInputStreamRegionAdapter::eof() const
|
|
+{
|
|
+ return getPosition() >= m_length;
|
|
+}
|
|
+
|
|
+
|
|
+void seekableInputStreamRegionAdapter::reset()
|
|
+{
|
|
+ m_stream->seek(m_begin);
|
|
+}
|
|
+
|
|
+
|
|
+stream::size_type seekableInputStreamRegionAdapter::read
|
|
+ (value_type* const data, const size_type count)
|
|
+{
|
|
+ if (getPosition() + count >= m_length)
|
|
+ {
|
|
+ const size_type remaining = m_length - getPosition();
|
|
+ return m_stream->read(data, remaining);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ return m_stream->read(data, count);
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+stream::size_type seekableInputStreamRegionAdapter::skip(const size_type count)
|
|
+{
|
|
+ if (getPosition() + count >= m_length)
|
|
+ {
|
|
+ const size_type remaining = m_length - getPosition();
|
|
+ m_stream->skip(remaining);
|
|
+ return remaining;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ m_stream->skip(count);
|
|
+ return count;
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+stream::size_type seekableInputStreamRegionAdapter::getPosition() const
|
|
+{
|
|
+ return m_stream->getPosition() - m_begin;
|
|
+}
|
|
+
|
|
+
|
|
+void seekableInputStreamRegionAdapter::seek(const size_type pos)
|
|
+{
|
|
+ m_stream->seek(m_begin + pos);
|
|
+}
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
diff --git a/src/utility/stream.cpp b/src/utility/stream.cpp
|
|
index 1c940c2..67c1f33 100644
|
|
--- a/src/utility/stream.cpp
|
|
+++ b/src/utility/stream.cpp
|
|
@@ -29,6 +29,9 @@ namespace vmime {
|
|
namespace utility {
|
|
|
|
|
|
+const stream::size_type stream::npos = static_cast <size_type>(vmime::string::npos);
|
|
+
|
|
+
|
|
stream::size_type stream::getBlockSize()
|
|
{
|
|
return 32768; // 32 KB
|
|
@@ -37,3 +40,4 @@ stream::size_type stream::getBlockSize()
|
|
|
|
} // utility
|
|
} // vmime
|
|
+
|
|
diff --git a/src/utility/streamUtils.cpp b/src/utility/streamUtils.cpp
|
|
index f1d3b9d..f7ea62f 100644
|
|
--- a/src/utility/streamUtils.cpp
|
|
+++ b/src/utility/streamUtils.cpp
|
|
@@ -52,6 +52,35 @@ stream::size_type bufferedStreamCopy(inputStream& is, outputStream& os)
|
|
}
|
|
|
|
|
|
+stream::size_type bufferedStreamCopyRange(inputStream& is, outputStream& os,
|
|
+ const stream::size_type start, const stream::size_type length)
|
|
+{
|
|
+ const stream::size_type blockSize =
|
|
+ std::min(is.getBlockSize(), os.getBlockSize());
|
|
+
|
|
+ is.skip(start);
|
|
+
|
|
+ std::vector <stream::value_type> vbuffer(blockSize);
|
|
+
|
|
+ stream::value_type* buffer = &vbuffer.front();
|
|
+ stream::size_type total = 0;
|
|
+
|
|
+ while (!is.eof() && total < length)
|
|
+ {
|
|
+ const stream::size_type remaining = std::min(length - total, blockSize);
|
|
+ const stream::size_type read = is.read(buffer, blockSize);
|
|
+
|
|
+ if (read != 0)
|
|
+ {
|
|
+ os.write(buffer, read);
|
|
+ total += read;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return total;
|
|
+}
|
|
+
|
|
+
|
|
stream::size_type bufferedStreamCopy(inputStream& is, outputStream& os,
|
|
const stream::size_type length, progressListener* progress)
|
|
{
|
|
diff --git a/src/word.cpp b/src/word.cpp
|
|
index 79060a1..2876ddf 100644
|
|
--- a/src/word.cpp
|
|
+++ b/src/word.cpp
|
|
@@ -241,7 +241,7 @@ const std::vector <ref <word> > word::parseMultiple(const string& buffer, const
|
|
}
|
|
|
|
|
|
-void word::parse(const string& buffer, const string::size_type position,
|
|
+void word::parseImpl(const string& buffer, const string::size_type position,
|
|
const string::size_type end, string::size_type* newPosition)
|
|
{
|
|
if (position + 6 < end && // 6 = "=?(.+)?(.*)?="
|
|
@@ -324,7 +324,7 @@ void word::parse(const string& buffer, const string::size_type position,
|
|
}
|
|
|
|
|
|
-void word::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
+void word::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
{
|
|
generate(os, maxLineLength, curLinePos, newLinePos, 0, NULL);
|
|
@@ -743,9 +743,9 @@ void word::setBuffer(const string& buffer)
|
|
}
|
|
|
|
|
|
-const std::vector <ref <const component> > word::getChildComponents() const
|
|
+const std::vector <ref <component> > word::getChildComponents()
|
|
{
|
|
- return std::vector <ref <const component> >();
|
|
+ return std::vector <ref <component> >();
|
|
}
|
|
|
|
|
|
diff --git a/tests/parser/bodyPartTest.cpp b/tests/parser/bodyPartTest.cpp
|
|
index 9d51262..deb4b9c 100644
|
|
--- a/tests/parser/bodyPartTest.cpp
|
|
+++ b/tests/parser/bodyPartTest.cpp
|
|
@@ -33,12 +33,14 @@ VMIME_TEST_SUITE_BEGIN
|
|
VMIME_TEST_LIST_BEGIN
|
|
VMIME_TEST(testParse)
|
|
VMIME_TEST(testGenerate)
|
|
+ VMIME_TEST(testParseGuessBoundary)
|
|
VMIME_TEST(testParseMissingLastBoundary)
|
|
VMIME_TEST(testPrologEpilog)
|
|
VMIME_TEST(testPrologEncoding)
|
|
VMIME_TEST(testSuccessiveBoundaries)
|
|
VMIME_TEST(testGenerate7bit)
|
|
VMIME_TEST(testTextUsageForQPEncoding)
|
|
+ VMIME_TEST(testParseVeryBigMessage)
|
|
VMIME_TEST_LIST_END
|
|
|
|
|
|
@@ -237,6 +239,93 @@ VMIME_TEST_SUITE_BEGIN
|
|
VASSERT_EQ("2", "Part1-line1\r\nPart1-line2\r\n=89", oss.str());
|
|
}
|
|
|
|
+ void testParseGuessBoundary()
|
|
+ {
|
|
+ // Boundary is not specified in "Content-Type" field
|
|
+ // Parser will try to guess it from message contents.
|
|
+
|
|
+ vmime::string str =
|
|
+ "Content-Type: multipart/mixed"
|
|
+ "\r\n\r\n"
|
|
+ "--UNKNOWN-BOUNDARY\r\nHEADER1\r\n\r\nBODY1\r\n"
|
|
+ "--UNKNOWN-BOUNDARY\r\nHEADER2\r\n\r\nBODY2\r\n"
|
|
+ "--UNKNOWN-BOUNDARY--";
|
|
+
|
|
+ vmime::bodyPart p;
|
|
+ p.parse(str);
|
|
+
|
|
+ VASSERT_EQ("count", 2, p.getBody()->getPartCount());
|
|
+
|
|
+ VASSERT_EQ("part1-body", "BODY1", extractContents(p.getBody()->getPartAt(0)->getBody()->getContents()));
|
|
+ VASSERT_EQ("part2-body", "BODY2", extractContents(p.getBody()->getPartAt(1)->getBody()->getContents()));
|
|
+ }
|
|
+
|
|
+ void testParseVeryBigMessage()
|
|
+ {
|
|
+ // When parsing from a seekable input stream, body contents should not
|
|
+ // be kept in memory in a "stringContentHandler" object. Instead, content
|
|
+ // should be accessible via a "streamContentHandler" object.
|
|
+
|
|
+ static const std::string BODY1_BEGIN = "BEGIN1BEGIN1BEGIN1";
|
|
+ static const std::string BODY1_LINE = "BODY1BODY1BODY1BODY1BODY1BODY1BODY1BODY1BODY1BODY1BODY1BODY1BODY1";
|
|
+ static const std::string BODY1_END = "END1END1";
|
|
+ static const unsigned int BODY1_REPEAT = 35000;
|
|
+ static const unsigned int BODY1_LENGTH =
|
|
+ BODY1_BEGIN.length() + BODY1_LINE.length() * BODY1_REPEAT + BODY1_END.length();
|
|
+
|
|
+ static const std::string BODY2_LINE = "BODY2BODY2BODY2BODY2BODY2BODY2BODY2BODY2BODY2BODY2BODY2BODY2BODY2";
|
|
+ static const unsigned int BODY2_REPEAT = 20000;
|
|
+
|
|
+ std::ostringstream oss;
|
|
+ oss << "Content-Type: multipart/mixed; boundary=\"MY-BOUNDARY\""
|
|
+ << "\r\n\r\n"
|
|
+ << "--MY-BOUNDARY\r\n"
|
|
+ << "HEADER1\r\n"
|
|
+ << "\r\n";
|
|
+
|
|
+ oss << BODY1_BEGIN;
|
|
+
|
|
+ for (unsigned int i = 0 ; i < BODY1_REPEAT ; ++i)
|
|
+ oss << BODY1_LINE;
|
|
+
|
|
+ oss << BODY1_END;
|
|
+
|
|
+ oss << "\r\n"
|
|
+ << "--MY-BOUNDARY\r\n"
|
|
+ << "HEADER2\r\n"
|
|
+ << "\r\n";
|
|
+
|
|
+ for (unsigned int i = 0 ; i < BODY2_REPEAT ; ++i)
|
|
+ oss << BODY2_LINE;
|
|
+
|
|
+ oss << "\r\n"
|
|
+ << "--MY-BOUNDARY--\r\n";
|
|
+
|
|
+ vmime::ref <vmime::utility::inputStreamStringAdapter> is =
|
|
+ vmime::create <vmime::utility::inputStreamStringAdapter>(oss.str());
|
|
+
|
|
+ vmime::ref <vmime::message> msg = vmime::create <vmime::message>();
|
|
+ msg->parse(is, oss.str().length());
|
|
+
|
|
+ vmime::ref <vmime::body> body1 = msg->getBody()->getPartAt(0)->getBody();
|
|
+ vmime::ref <const vmime::contentHandler> body1Cts = body1->getContents();
|
|
+
|
|
+ vmime::ref <vmime::body> body2 = msg->getBody()->getPartAt(1)->getBody();
|
|
+ vmime::ref <const vmime::contentHandler> body2Cts = body2->getContents();
|
|
+
|
|
+ vmime::string body1CtsExtracted;
|
|
+ vmime::utility::outputStreamStringAdapter body1CtsExtractStream(body1CtsExtracted);
|
|
+ body1Cts->extract(body1CtsExtractStream);
|
|
+
|
|
+ VASSERT_EQ("1.1", BODY1_LENGTH, body1Cts->getLength());
|
|
+ VASSERT("1.2", body1Cts.dynamicCast <const vmime::streamContentHandler>() != NULL);
|
|
+ VASSERT_EQ("1.3", BODY1_LENGTH, body1CtsExtracted.length());
|
|
+ VASSERT_EQ("1.4", BODY1_BEGIN, body1CtsExtracted.substr(0, BODY1_BEGIN.length()));
|
|
+ VASSERT_EQ("1.5", BODY1_END, body1CtsExtracted.substr(BODY1_LENGTH - BODY1_END.length(), BODY1_END.length()));
|
|
+
|
|
+ VASSERT_EQ("2.1", BODY2_LINE.length() * BODY2_REPEAT, body2Cts->getLength());
|
|
+ VASSERT("2.2", body2Cts.dynamicCast <const vmime::streamContentHandler>() != NULL);
|
|
+ }
|
|
|
|
VMIME_TEST_SUITE_END
|
|
|
|
diff --git a/vmime/addressList.hpp b/vmime/addressList.hpp
|
|
index 2e537c0..9dc283c 100644
|
|
--- a/vmime/addressList.hpp
|
|
+++ b/vmime/addressList.hpp
|
|
@@ -56,7 +56,7 @@ public:
|
|
addressList& operator=(const addressList& other);
|
|
addressList& operator=(const mailboxList& other);
|
|
|
|
- const std::vector <ref <const component> > getChildComponents() const;
|
|
+ const std::vector <ref <component> > getChildComponents();
|
|
|
|
|
|
/** Add a address at the end of the list.
|
|
@@ -163,14 +163,20 @@ private:
|
|
|
|
std::vector <ref <address> > m_list;
|
|
|
|
-public:
|
|
-
|
|
- using component::parse;
|
|
- using component::generate;
|
|
+protected:
|
|
|
|
// Component parsing & assembling
|
|
- void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
+ void parseImpl
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition = NULL);
|
|
+
|
|
+ void generateImpl
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
};
|
|
|
|
|
|
diff --git a/vmime/body.hpp b/vmime/body.hpp
|
|
index 9e83d6b..bd5bbb9 100644
|
|
--- a/vmime/body.hpp
|
|
+++ b/vmime/body.hpp
|
|
@@ -278,7 +278,7 @@ public:
|
|
void copyFrom(const component& other);
|
|
body& operator=(const body& other);
|
|
|
|
- const std::vector <ref <const component> > getChildComponents() const;
|
|
+ const std::vector <ref <component> > getChildComponents();
|
|
|
|
private:
|
|
|
|
@@ -299,14 +299,20 @@ private:
|
|
|
|
void initNewPart(ref <bodyPart> part);
|
|
|
|
-public:
|
|
-
|
|
- using component::parse;
|
|
- using component::generate;
|
|
+protected:
|
|
|
|
// Component parsing & assembling
|
|
- void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
+ void parseImpl
|
|
+ (ref <utility::parserInputStreamAdapter> parser,
|
|
+ const utility::stream::size_type position,
|
|
+ const utility::stream::size_type end,
|
|
+ utility::stream::size_type* newPosition = NULL);
|
|
+
|
|
+ void generateImpl
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
};
|
|
|
|
|
|
diff --git a/vmime/bodyPart.hpp b/vmime/bodyPart.hpp
|
|
index aa0f040..5f36d90 100644
|
|
--- a/vmime/bodyPart.hpp
|
|
+++ b/vmime/bodyPart.hpp
|
|
@@ -89,7 +89,7 @@ public:
|
|
void copyFrom(const component& other);
|
|
bodyPart& operator=(const bodyPart& other);
|
|
|
|
- const std::vector <ref <const component> > getChildComponents() const;
|
|
+ const std::vector <ref <component> > getChildComponents();
|
|
|
|
private:
|
|
|
|
@@ -98,14 +98,20 @@ private:
|
|
|
|
weak_ref <bodyPart> m_parent;
|
|
|
|
-public:
|
|
-
|
|
- using component::parse;
|
|
- using component::generate;
|
|
+protected:
|
|
|
|
// Component parsing & assembling
|
|
- void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
+ void parseImpl
|
|
+ (ref <utility::parserInputStreamAdapter> parser,
|
|
+ const utility::stream::size_type position,
|
|
+ const utility::stream::size_type end,
|
|
+ utility::stream::size_type* newPosition = NULL);
|
|
+
|
|
+ void generateImpl
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
};
|
|
|
|
|
|
diff --git a/vmime/charset.hpp b/vmime/charset.hpp
|
|
index 5f5e8e5..26abb4f 100644
|
|
--- a/vmime/charset.hpp
|
|
+++ b/vmime/charset.hpp
|
|
@@ -62,7 +62,7 @@ public:
|
|
bool operator==(const charset& value) const;
|
|
bool operator!=(const charset& value) const;
|
|
|
|
- const std::vector <ref <const component> > getChildComponents() const;
|
|
+ const std::vector <ref <component> > getChildComponents();
|
|
|
|
/** Gets the recommended encoding for this charset.
|
|
* Note: there may be no recommended encoding.
|
|
@@ -117,14 +117,20 @@ private:
|
|
|
|
string m_name;
|
|
|
|
-public:
|
|
-
|
|
- using component::parse;
|
|
- using component::generate;
|
|
+protected:
|
|
|
|
// Component parsing & assembling
|
|
- void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
+ void parseImpl
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition = NULL);
|
|
+
|
|
+ void generateImpl
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
};
|
|
|
|
|
|
diff --git a/vmime/component.hpp b/vmime/component.hpp
|
|
index 12b0406..5e6f393 100644
|
|
--- a/vmime/component.hpp
|
|
+++ b/vmime/component.hpp
|
|
@@ -27,6 +27,8 @@
|
|
|
|
#include "vmime/base.hpp"
|
|
#include "vmime/utility/inputStream.hpp"
|
|
+#include "vmime/utility/seekableInputStream.hpp"
|
|
+#include "vmime/utility/parserInputStreamAdapter.hpp"
|
|
#include "vmime/utility/outputStream.hpp"
|
|
|
|
|
|
@@ -51,6 +53,12 @@ public:
|
|
*/
|
|
void parse(const string& buffer);
|
|
|
|
+ /** Parse RFC-822/MIME data for this component. If stream is not seekable,
|
|
+ * or if length is not specified, entire contents of the stream will
|
|
+ * be loaded into memory before parsing.
|
|
+ */
|
|
+ void parse(ref <utility::inputStream> inputStream, const utility::stream::size_type length);
|
|
+
|
|
/** Parse RFC-822/MIME data for this component.
|
|
*
|
|
* @param buffer input buffer
|
|
@@ -58,7 +66,26 @@ public:
|
|
* @param end end position in the input buffer
|
|
* @param newPosition will receive the new position in the input buffer
|
|
*/
|
|
- virtual void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL) = 0;
|
|
+ void parse
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition = NULL);
|
|
+
|
|
+ /** Parse RFC-822/MIME data for this component. If stream is not seekable,
|
|
+ * or if end position is not specified, entire contents of the stream will
|
|
+ * be loaded into memory before parsing.
|
|
+ *
|
|
+ * @param inputStream stream from which to read data
|
|
+ * @param position current position in the input stream
|
|
+ * @param end end position in the input stream
|
|
+ * @param newPosition will receive the new position in the input stream
|
|
+ */
|
|
+ void parse
|
|
+ (ref <utility::inputStream> inputStream,
|
|
+ const utility::stream::size_type position,
|
|
+ const utility::stream::size_type end,
|
|
+ utility::stream::size_type* newPosition = NULL);
|
|
|
|
/** Generate RFC-2822/MIME data for this component.
|
|
*
|
|
@@ -68,16 +95,35 @@ public:
|
|
* @param curLinePos length of the current line in the output buffer
|
|
* @return generated data
|
|
*/
|
|
- const string generate(const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0) const;
|
|
+ virtual const string generate
|
|
+ (const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0) const;
|
|
|
|
/** Generate RFC-2822/MIME data for this component.
|
|
*
|
|
- * @param os output stream
|
|
+ * @param outputStream output stream
|
|
* @param maxLineLength maximum line length for output
|
|
* @param curLinePos length of the current line in the output buffer
|
|
* @param newLinePos will receive the new line position (length of the last line written)
|
|
*/
|
|
- virtual void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const = 0;
|
|
+ virtual void generate
|
|
+ (utility::outputStream& outputStream,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
+
|
|
+ /** Generate RFC-2822/MIME data for this component.
|
|
+ *
|
|
+ * @param outputStream output stream
|
|
+ * @param maxLineLength maximum line length for output
|
|
+ * @param curLinePos length of the current line in the output buffer
|
|
+ * @param newLinePos will receive the new line position (length of the last line written)
|
|
+ */
|
|
+ virtual void generate
|
|
+ (ref <utility::outputStream> outputStream,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
|
|
/** Clone this component.
|
|
*
|
|
@@ -95,41 +141,56 @@ public:
|
|
virtual void copyFrom(const component& other) = 0;
|
|
|
|
/** Return the start position of this component in the
|
|
- * parsed message contents.
|
|
+ * parsed message contents. Use for debugging only.
|
|
*
|
|
* @return start position in parsed buffer
|
|
* or 0 if this component has not been parsed
|
|
*/
|
|
- string::size_type getParsedOffset() const;
|
|
+ utility::stream::size_type getParsedOffset() const;
|
|
|
|
/** Return the length of this component in the
|
|
- * parsed message contents.
|
|
+ * parsed message contents. Use for debugging only.
|
|
*
|
|
* @return length of the component in parsed buffer
|
|
* or 0 if this component has not been parsed
|
|
*/
|
|
- string::size_type getParsedLength() const;
|
|
+ utility::stream::size_type getParsedLength() const;
|
|
|
|
/** Return the list of children of this component.
|
|
*
|
|
* @return list of child components
|
|
*/
|
|
- const std::vector <ref <component> > getChildComponents();
|
|
-
|
|
- /** Return the list of children of this component (const version).
|
|
- *
|
|
- * @return list of child components
|
|
- */
|
|
- virtual const std::vector <ref <const component> > getChildComponents() const = 0;
|
|
+ virtual const std::vector <ref <component> > getChildComponents() = 0;
|
|
|
|
protected:
|
|
|
|
- void setParsedBounds(const string::size_type start, const string::size_type end);
|
|
+ void setParsedBounds(const utility::stream::size_type start, const utility::stream::size_type end);
|
|
+
|
|
+ // AT LEAST ONE of these parseImpl() functions MUST be implemented in derived class
|
|
+ virtual void parseImpl
|
|
+ (ref <utility::parserInputStreamAdapter> parser,
|
|
+ const utility::stream::size_type position,
|
|
+ const utility::stream::size_type end,
|
|
+ utility::stream::size_type* newPosition = NULL);
|
|
+
|
|
+ virtual void parseImpl
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition = NULL);
|
|
+
|
|
+ virtual void generateImpl
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const = 0;
|
|
|
|
private:
|
|
|
|
- string::size_type m_parsedOffset;
|
|
- string::size_type m_parsedLength;
|
|
+ void offsetParsedBounds(const utility::stream::size_type offset);
|
|
+
|
|
+ utility::stream::size_type m_parsedOffset;
|
|
+ utility::stream::size_type m_parsedLength;
|
|
};
|
|
|
|
|
|
diff --git a/vmime/contentDisposition.hpp b/vmime/contentDisposition.hpp
|
|
index 9d1749b..abd2e1a 100644
|
|
--- a/vmime/contentDisposition.hpp
|
|
+++ b/vmime/contentDisposition.hpp
|
|
@@ -63,7 +63,7 @@ public:
|
|
void copyFrom(const component& other);
|
|
contentDisposition& operator=(const contentDisposition& other);
|
|
|
|
- const std::vector <ref <const component> > getChildComponents() const;
|
|
+ const std::vector <ref <component> > getChildComponents();
|
|
|
|
|
|
contentDisposition& operator=(const string& name);
|
|
@@ -75,14 +75,20 @@ private:
|
|
|
|
string m_name;
|
|
|
|
-public:
|
|
-
|
|
- using component::parse;
|
|
- using component::generate;
|
|
+protected:
|
|
|
|
// Component parsing & assembling
|
|
- void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
+ void parseImpl
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition = NULL);
|
|
+
|
|
+ void generateImpl
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
};
|
|
|
|
|
|
diff --git a/vmime/dateTime.hpp b/vmime/dateTime.hpp
|
|
index 8e99640..053f4a6 100644
|
|
--- a/vmime/dateTime.hpp
|
|
+++ b/vmime/dateTime.hpp
|
|
@@ -237,16 +237,22 @@ public:
|
|
// Current date and time
|
|
static const datetime now();
|
|
|
|
- const std::vector <ref <const component> > getChildComponents() const;
|
|
+ const std::vector <ref <component> > getChildComponents();
|
|
|
|
-public:
|
|
-
|
|
- using component::parse;
|
|
- using component::generate;
|
|
+protected:
|
|
|
|
// Component parsing & assembling
|
|
- void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
+ void parseImpl
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition = NULL);
|
|
+
|
|
+ void generateImpl
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
};
|
|
|
|
|
|
diff --git a/vmime/disposition.hpp b/vmime/disposition.hpp
|
|
index 05bfca2..7bdc832 100644
|
|
--- a/vmime/disposition.hpp
|
|
+++ b/vmime/disposition.hpp
|
|
@@ -50,7 +50,7 @@ public:
|
|
void copyFrom(const component& other);
|
|
disposition& operator=(const disposition& other);
|
|
|
|
- const std::vector <ref <const component> > getChildComponents() const;
|
|
+ const std::vector <ref <component> > getChildComponents();
|
|
|
|
|
|
/** Set the disposition action mode.
|
|
@@ -134,14 +134,20 @@ private:
|
|
|
|
std::vector <string> m_modifiers;
|
|
|
|
-public:
|
|
-
|
|
- using component::parse;
|
|
- using component::generate;
|
|
+protected:
|
|
|
|
// Component parsing & assembling
|
|
- void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
+ void parseImpl
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition = NULL);
|
|
+
|
|
+ void generateImpl
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
};
|
|
|
|
|
|
diff --git a/vmime/encoding.hpp b/vmime/encoding.hpp
|
|
index 42f5246..4322b29 100644
|
|
--- a/vmime/encoding.hpp
|
|
+++ b/vmime/encoding.hpp
|
|
@@ -93,7 +93,7 @@ public:
|
|
bool operator==(const encoding& value) const;
|
|
bool operator!=(const encoding& value) const;
|
|
|
|
- const std::vector <ref <const component> > getChildComponents() const;
|
|
+ const std::vector <ref <component> > getChildComponents();
|
|
|
|
/** Decide which encoding to use based on the specified data.
|
|
*
|
|
@@ -141,14 +141,20 @@ private:
|
|
*/
|
|
static const encoding decideImpl(const string::const_iterator begin, const string::const_iterator end);
|
|
|
|
-public:
|
|
-
|
|
- using component::parse;
|
|
- using component::generate;
|
|
+protected:
|
|
|
|
// Component parsing & assembling
|
|
- void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
+ void parseImpl
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition = NULL);
|
|
+
|
|
+ void generateImpl
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
};
|
|
|
|
|
|
diff --git a/vmime/header.hpp b/vmime/header.hpp
|
|
index 95a9326..ed555b0 100644
|
|
--- a/vmime/header.hpp
|
|
+++ b/vmime/header.hpp
|
|
@@ -220,7 +220,7 @@ public:
|
|
void copyFrom(const component& other);
|
|
header& operator=(const header& other);
|
|
|
|
- const std::vector <ref <const component> > getChildComponents() const;
|
|
+ const std::vector <ref <component> > getChildComponents();
|
|
|
|
private:
|
|
|
|
@@ -251,14 +251,20 @@ private:
|
|
string m_name;
|
|
};
|
|
|
|
-public:
|
|
-
|
|
- using component::parse;
|
|
- using component::generate;
|
|
+protected:
|
|
|
|
// Component parsing & assembling
|
|
- void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
+ void parseImpl
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition = NULL);
|
|
+
|
|
+ void generateImpl
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
};
|
|
|
|
|
|
diff --git a/vmime/headerField.hpp b/vmime/headerField.hpp
|
|
index 50494c9..61e01ee 100644
|
|
--- a/vmime/headerField.hpp
|
|
+++ b/vmime/headerField.hpp
|
|
@@ -59,7 +59,7 @@ public:
|
|
void copyFrom(const component& other);
|
|
headerField& operator=(const headerField& other);
|
|
|
|
- const std::vector <ref <const component> > getChildComponents() const;
|
|
+ const std::vector <ref <component> > getChildComponents();
|
|
|
|
/** Sets the name of this field.
|
|
*
|
|
@@ -118,15 +118,26 @@ public:
|
|
void setValue(const string& value);
|
|
|
|
|
|
- using component::parse;
|
|
- using component::generate;
|
|
+protected:
|
|
|
|
- void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
+ void parseImpl
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition = NULL);
|
|
+
|
|
+ void generateImpl
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
|
|
-protected:
|
|
|
|
- static ref <headerField> parseNext(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
+ static ref <headerField> parseNext
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition = NULL);
|
|
|
|
|
|
string m_name;
|
|
diff --git a/vmime/mailbox.hpp b/vmime/mailbox.hpp
|
|
index 2072be8..2099355 100644
|
|
--- a/vmime/mailbox.hpp
|
|
+++ b/vmime/mailbox.hpp
|
|
@@ -85,7 +85,7 @@ public:
|
|
|
|
void clear();
|
|
|
|
- const std::vector <ref <const component> > getChildComponents() const;
|
|
+ const std::vector <ref <component> > getChildComponents();
|
|
|
|
|
|
bool isGroup() const;
|
|
@@ -101,8 +101,17 @@ public:
|
|
using address::generate;
|
|
|
|
// Component parsing & assembling
|
|
- void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
+ void parseImpl
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition = NULL);
|
|
+
|
|
+ void generateImpl
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
};
|
|
|
|
|
|
diff --git a/vmime/mailboxGroup.hpp b/vmime/mailboxGroup.hpp
|
|
index 0061d5b..1433141 100644
|
|
--- a/vmime/mailboxGroup.hpp
|
|
+++ b/vmime/mailboxGroup.hpp
|
|
@@ -52,7 +52,7 @@ public:
|
|
ref <component> clone() const;
|
|
mailboxGroup& operator=(const component& other);
|
|
|
|
- const std::vector <ref <const component> > getChildComponents() const;
|
|
+ const std::vector <ref <component> > getChildComponents();
|
|
|
|
/** Return the name of the group.
|
|
*
|
|
@@ -165,14 +165,20 @@ private:
|
|
text m_name;
|
|
std::vector <ref <mailbox> > m_list;
|
|
|
|
-public:
|
|
-
|
|
- using address::parse;
|
|
- using address::generate;
|
|
+protected:
|
|
|
|
// Component parsing & assembling
|
|
- void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
+ void parseImpl
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition = NULL);
|
|
+
|
|
+ void generateImpl
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
};
|
|
|
|
|
|
diff --git a/vmime/mailboxList.hpp b/vmime/mailboxList.hpp
|
|
index 11e4e79..1b480c1 100644
|
|
--- a/vmime/mailboxList.hpp
|
|
+++ b/vmime/mailboxList.hpp
|
|
@@ -51,7 +51,7 @@ public:
|
|
void copyFrom(const component& other);
|
|
mailboxList& operator=(const mailboxList& other);
|
|
|
|
- const std::vector <ref <const component> > getChildComponents() const;
|
|
+ const std::vector <ref <component> > getChildComponents();
|
|
|
|
/** Add a mailbox at the end of the list.
|
|
*
|
|
@@ -155,14 +155,20 @@ private:
|
|
|
|
addressList m_list;
|
|
|
|
-public:
|
|
-
|
|
- using component::parse;
|
|
- using component::generate;
|
|
+protected:
|
|
|
|
// Component parsing & assembling
|
|
- void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
+ void parseImpl
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition = NULL);
|
|
+
|
|
+ void generateImpl
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
};
|
|
|
|
|
|
diff --git a/vmime/mediaType.hpp b/vmime/mediaType.hpp
|
|
index 658b21f..18182f0 100644
|
|
--- a/vmime/mediaType.hpp
|
|
+++ b/vmime/mediaType.hpp
|
|
@@ -55,7 +55,7 @@ public:
|
|
void copyFrom(const component& other);
|
|
mediaType& operator=(const mediaType& other);
|
|
|
|
- const std::vector <ref <const component> > getChildComponents() const;
|
|
+ const std::vector <ref <component> > getChildComponents();
|
|
|
|
/** Return the media type.
|
|
* See the constants in vmime::mediaTypes.
|
|
@@ -97,14 +97,18 @@ protected:
|
|
string m_type;
|
|
string m_subType;
|
|
|
|
-public:
|
|
-
|
|
- using component::parse;
|
|
- using component::generate;
|
|
-
|
|
// Component parsing & assembling
|
|
- void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
+ void parseImpl
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition = NULL);
|
|
+
|
|
+ void generateImpl
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
};
|
|
|
|
|
|
diff --git a/vmime/message.hpp b/vmime/message.hpp
|
|
index f3be229..9767564 100644
|
|
--- a/vmime/message.hpp
|
|
+++ b/vmime/message.hpp
|
|
@@ -43,12 +43,25 @@ public:
|
|
message();
|
|
|
|
|
|
- // Component parsing & assembling
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength = options::getInstance()->message.maxLineLength(), const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
-
|
|
- const string generate(const string::size_type maxLineLength = options::getInstance()->message.maxLineLength(), const string::size_type curLinePos = 0) const;
|
|
+public:
|
|
|
|
- void parse(const string& buffer);
|
|
+ // Override default generate() functions so that we can change
|
|
+ // the default 'maxLineLength' value
|
|
+ void generate
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = options::getInstance()->message.maxLineLength(),
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
+
|
|
+ const string generate
|
|
+ (const string::size_type maxLineLength = options::getInstance()->message.maxLineLength(),
|
|
+ const string::size_type curLinePos = 0) const;
|
|
+
|
|
+ void generate
|
|
+ (ref <utility::outputStream> os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
};
|
|
|
|
|
|
diff --git a/vmime/messageId.hpp b/vmime/messageId.hpp
|
|
index 3686b11..ac408e6 100644
|
|
--- a/vmime/messageId.hpp
|
|
+++ b/vmime/messageId.hpp
|
|
@@ -97,23 +97,27 @@ public:
|
|
void copyFrom(const component& other);
|
|
messageId& operator=(const messageId& other);
|
|
|
|
- const std::vector <ref <const component> > getChildComponents() const;
|
|
+ const std::vector <ref <component> > getChildComponents();
|
|
|
|
private:
|
|
|
|
string m_left;
|
|
string m_right;
|
|
|
|
-public:
|
|
-
|
|
- using component::parse;
|
|
- using component::generate;
|
|
+protected:
|
|
|
|
// Component parsing & assembling
|
|
- void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
-
|
|
-protected:
|
|
+ void parseImpl
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition = NULL);
|
|
+
|
|
+ void generateImpl
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
|
|
/** Parse a message-id from an input buffer.
|
|
*
|
|
@@ -123,7 +127,11 @@ protected:
|
|
* @param newPosition will receive the new position in the input buffer
|
|
* @return a new message-id object, or null if no more message-id can be parsed from the input buffer
|
|
*/
|
|
- static ref <messageId> parseNext(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition);
|
|
+ static ref <messageId> parseNext
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition);
|
|
};
|
|
|
|
|
|
diff --git a/vmime/messageIdSequence.hpp b/vmime/messageIdSequence.hpp
|
|
index 5dfb840..6736d0a 100644
|
|
--- a/vmime/messageIdSequence.hpp
|
|
+++ b/vmime/messageIdSequence.hpp
|
|
@@ -49,7 +49,7 @@ public:
|
|
void copyFrom(const component& other);
|
|
messageIdSequence& operator=(const messageIdSequence& other);
|
|
|
|
- const std::vector <ref <const component> > getChildComponents() const;
|
|
+ const std::vector <ref <component> > getChildComponents();
|
|
|
|
|
|
/** Add a message-id at the end of the list.
|
|
@@ -148,14 +148,20 @@ private:
|
|
|
|
std::vector <ref <messageId> > m_list;
|
|
|
|
-public:
|
|
-
|
|
- using component::parse;
|
|
- using component::generate;
|
|
+protected:
|
|
|
|
// Component parsing & assembling
|
|
- void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
+ void parseImpl
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition = NULL);
|
|
+
|
|
+ void generateImpl
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
};
|
|
|
|
|
|
diff --git a/vmime/parameter.hpp b/vmime/parameter.hpp
|
|
index e1b13a1..0773ea6 100644
|
|
--- a/vmime/parameter.hpp
|
|
+++ b/vmime/parameter.hpp
|
|
@@ -67,7 +67,7 @@ public:
|
|
void copyFrom(const component& other);
|
|
parameter& operator=(const parameter& other);
|
|
|
|
- const std::vector <ref <const component> > getChildComponents() const;
|
|
+ const std::vector <ref <component> > getChildComponents();
|
|
|
|
/** Return the name of this parameter.
|
|
*
|
|
@@ -104,7 +104,7 @@ public:
|
|
const T getValueAs() const
|
|
{
|
|
T ret;
|
|
- ret.parse(m_value.getBuffer());
|
|
+ ret.parse(m_value->getBuffer());
|
|
|
|
return ret;
|
|
}
|
|
@@ -122,11 +122,19 @@ public:
|
|
void setValue(const word& value);
|
|
|
|
|
|
- using component::parse;
|
|
- using component::generate;
|
|
+protected:
|
|
|
|
- void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
+ void parseImpl
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition = NULL);
|
|
+
|
|
+ void generateImpl
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
|
|
private:
|
|
|
|
@@ -134,7 +142,7 @@ private:
|
|
|
|
|
|
string m_name;
|
|
- word m_value;
|
|
+ ref <word> m_value;
|
|
};
|
|
|
|
|
|
diff --git a/vmime/parameterizedHeaderField.hpp b/vmime/parameterizedHeaderField.hpp
|
|
index 2940ca3..d2c934f 100644
|
|
--- a/vmime/parameterizedHeaderField.hpp
|
|
+++ b/vmime/parameterizedHeaderField.hpp
|
|
@@ -172,19 +172,25 @@ public:
|
|
*/
|
|
const std::vector <ref <parameter> > getParameterList();
|
|
|
|
+ const std::vector <ref <component> > getChildComponents();
|
|
+
|
|
private:
|
|
|
|
std::vector <ref <parameter> > m_params;
|
|
|
|
-public:
|
|
-
|
|
- using headerField::parse;
|
|
- using headerField::generate;
|
|
-
|
|
- void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
+protected:
|
|
|
|
- const std::vector <ref <const component> > getChildComponents() const;
|
|
+ void parseImpl
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition = NULL);
|
|
+
|
|
+ void generateImpl
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
};
|
|
|
|
|
|
diff --git a/vmime/parserHelpers.hpp b/vmime/parserHelpers.hpp
|
|
index 9b075f7..d4f1246 100644
|
|
--- a/vmime/parserHelpers.hpp
|
|
+++ b/vmime/parserHelpers.hpp
|
|
@@ -45,6 +45,10 @@ public:
|
|
return (c == ' ' || c == '\t' || c == '\n' || c == '\r');
|
|
}
|
|
|
|
+ static bool isSpaceOrTab(const char_t c)
|
|
+ {
|
|
+ return (c == ' ' || c == '\t');
|
|
+ }
|
|
|
|
static bool isDigit(const char_t c)
|
|
{
|
|
diff --git a/vmime/path.hpp b/vmime/path.hpp
|
|
index beaa72b..eec8dfc 100644
|
|
--- a/vmime/path.hpp
|
|
+++ b/vmime/path.hpp
|
|
@@ -76,21 +76,26 @@ public:
|
|
ref <component> clone() const;
|
|
path& operator=(const path& other);
|
|
|
|
- const std::vector <ref <const component> > getChildComponents() const;
|
|
+ const std::vector <ref <component> > getChildComponents();
|
|
|
|
protected:
|
|
|
|
string m_localPart;
|
|
string m_domain;
|
|
|
|
-public:
|
|
-
|
|
- using component::parse;
|
|
- using component::generate;
|
|
|
|
// Component parsing & assembling
|
|
- void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
+ void parseImpl
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition = NULL);
|
|
+
|
|
+ void generateImpl
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
};
|
|
|
|
|
|
diff --git a/vmime/platforms/posix/posixFile.hpp b/vmime/platforms/posix/posixFile.hpp
|
|
index 70986df..704b7b0 100644
|
|
--- a/vmime/platforms/posix/posixFile.hpp
|
|
+++ b/vmime/platforms/posix/posixFile.hpp
|
|
@@ -26,6 +26,7 @@
|
|
|
|
|
|
#include "vmime/utility/file.hpp"
|
|
+#include "vmime/utility/seekableInputStream.hpp"
|
|
|
|
|
|
#if VMIME_HAVE_FILESYSTEM_FEATURES
|
|
@@ -57,7 +58,7 @@ private:
|
|
|
|
|
|
|
|
-class posixFileReaderInputStream : public vmime::utility::inputStream
|
|
+class posixFileReaderInputStream : public vmime::utility::seekableInputStream
|
|
{
|
|
public:
|
|
|
|
@@ -72,6 +73,9 @@ public:
|
|
|
|
size_type skip(const size_type count);
|
|
|
|
+ size_type getPosition() const;
|
|
+ void seek(const size_type pos);
|
|
+
|
|
private:
|
|
|
|
const vmime::utility::file::path m_path;
|
|
diff --git a/vmime/platforms/windows/windowsFile.hpp b/vmime/platforms/windows/windowsFile.hpp
|
|
index 6e1c8fb..f417032 100644
|
|
--- a/vmime/platforms/windows/windowsFile.hpp
|
|
+++ b/vmime/platforms/windows/windowsFile.hpp
|
|
@@ -26,6 +26,7 @@
|
|
|
|
|
|
#include "vmime/utility/file.hpp"
|
|
+#include "vmime/utility/seekableInputStream.hpp"
|
|
|
|
#include <windows.h>
|
|
|
|
@@ -157,6 +158,8 @@ public:
|
|
void reset();
|
|
size_type read(value_type* const data, const size_type count);
|
|
size_type skip(const size_type count);
|
|
+ size_type getPosition() const;
|
|
+ void seek(const size_type pos);
|
|
|
|
private:
|
|
|
|
diff --git a/vmime/relay.hpp b/vmime/relay.hpp
|
|
index 583ad80..dbaedf2 100644
|
|
--- a/vmime/relay.hpp
|
|
+++ b/vmime/relay.hpp
|
|
@@ -51,7 +51,7 @@ public:
|
|
void copyFrom(const component& other);
|
|
relay& operator=(const relay& other);
|
|
|
|
- const std::vector <ref <const component> > getChildComponents() const;
|
|
+ const std::vector <ref <component> > getChildComponents();
|
|
|
|
const string& getFrom() const;
|
|
void setFrom(const string& from);
|
|
@@ -85,13 +85,19 @@ private:
|
|
|
|
datetime m_date;
|
|
|
|
-public:
|
|
+protected:
|
|
|
|
- using component::parse;
|
|
- using component::generate;
|
|
+ void parseImpl
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition = NULL);
|
|
|
|
- void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
+ void generateImpl
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
};
|
|
|
|
|
|
diff --git a/vmime/text.hpp b/vmime/text.hpp
|
|
index 15e11ae..778ce86 100644
|
|
--- a/vmime/text.hpp
|
|
+++ b/vmime/text.hpp
|
|
@@ -58,7 +58,7 @@ public:
|
|
text& operator=(const component& other);
|
|
text& operator=(const text& other);
|
|
|
|
- const std::vector <ref <const component> > getChildComponents() const;
|
|
+ const std::vector <ref <component> > getChildComponents();
|
|
|
|
/** Add a word at the end of the list.
|
|
*
|
|
@@ -226,13 +226,20 @@ public:
|
|
*/
|
|
static text* decodeAndUnfold(const string& in, text* generateInExisting);
|
|
|
|
-
|
|
- using component::parse;
|
|
- using component::generate;
|
|
+protected:
|
|
|
|
// Component parsing & assembling
|
|
- void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
+ void parseImpl
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition = NULL);
|
|
+
|
|
+ void generateImpl
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
|
|
private:
|
|
|
|
diff --git a/vmime/utility/inputStreamAdapter.hpp b/vmime/utility/inputStreamAdapter.hpp
|
|
index 278ab52..bd4d21e 100644
|
|
--- a/vmime/utility/inputStreamAdapter.hpp
|
|
+++ b/vmime/utility/inputStreamAdapter.hpp
|
|
@@ -25,7 +25,7 @@
|
|
#define VMIME_UTILITY_INPUTSTREAMADAPTER_HPP_INCLUDED
|
|
|
|
|
|
-#include "vmime/utility/inputStream.hpp"
|
|
+#include "vmime/utility/seekableInputStream.hpp"
|
|
|
|
#include <istream>
|
|
|
|
@@ -37,7 +37,7 @@ namespace utility {
|
|
/** An adapter class for C++ standard input streams.
|
|
*/
|
|
|
|
-class inputStreamAdapter : public inputStream
|
|
+class inputStreamAdapter : public seekableInputStream
|
|
{
|
|
public:
|
|
|
|
@@ -49,6 +49,8 @@ public:
|
|
void reset();
|
|
size_type read(value_type* const data, const size_type count);
|
|
size_type skip(const size_type count);
|
|
+ size_type getPosition() const;
|
|
+ void seek(const size_type pos);
|
|
|
|
private:
|
|
|
|
diff --git a/vmime/utility/inputStreamByteBufferAdapter.hpp b/vmime/utility/inputStreamByteBufferAdapter.hpp
|
|
index 0f6a442..b3dafd9 100644
|
|
--- a/vmime/utility/inputStreamByteBufferAdapter.hpp
|
|
+++ b/vmime/utility/inputStreamByteBufferAdapter.hpp
|
|
@@ -25,7 +25,7 @@
|
|
#define VMIME_UTILITY_INPUTSTREAMBYTEBUFFERADAPTER_HPP_INCLUDED
|
|
|
|
|
|
-#include "vmime/utility/inputStream.hpp"
|
|
+#include "vmime/utility/seekableInputStream.hpp"
|
|
|
|
|
|
namespace vmime {
|
|
@@ -35,7 +35,7 @@ namespace utility {
|
|
/** An adapter class for reading from an array of bytes.
|
|
*/
|
|
|
|
-class inputStreamByteBufferAdapter : public inputStream
|
|
+class inputStreamByteBufferAdapter : public seekableInputStream
|
|
{
|
|
public:
|
|
|
|
@@ -45,6 +45,8 @@ public:
|
|
void reset();
|
|
size_type read(value_type* const data, const size_type count);
|
|
size_type skip(const size_type count);
|
|
+ size_type getPosition() const;
|
|
+ void seek(const size_type pos);
|
|
|
|
private:
|
|
|
|
diff --git a/vmime/utility/inputStreamStringAdapter.hpp b/vmime/utility/inputStreamStringAdapter.hpp
|
|
index a7d986f..18a9083 100644
|
|
--- a/vmime/utility/inputStreamStringAdapter.hpp
|
|
+++ b/vmime/utility/inputStreamStringAdapter.hpp
|
|
@@ -25,7 +25,7 @@
|
|
#define VMIME_UTILITY_INPUTSTREAMSTRINGADAPTER_HPP_INCLUDED
|
|
|
|
|
|
-#include "vmime/utility/inputStream.hpp"
|
|
+#include "vmime/utility/seekableInputStream.hpp"
|
|
|
|
|
|
namespace vmime {
|
|
@@ -35,7 +35,7 @@ namespace utility {
|
|
/** An adapter class for string input.
|
|
*/
|
|
|
|
-class inputStreamStringAdapter : public inputStream
|
|
+class inputStreamStringAdapter : public seekableInputStream
|
|
{
|
|
public:
|
|
|
|
@@ -46,6 +46,8 @@ public:
|
|
void reset();
|
|
size_type read(value_type* const data, const size_type count);
|
|
size_type skip(const size_type count);
|
|
+ size_type getPosition() const;
|
|
+ void seek(const size_type pos);
|
|
|
|
private:
|
|
|
|
diff --git a/vmime/utility/inputStreamStringProxyAdapter.hpp b/vmime/utility/inputStreamStringProxyAdapter.hpp
|
|
index 74b3f60..dc52637 100644
|
|
--- a/vmime/utility/inputStreamStringProxyAdapter.hpp
|
|
+++ b/vmime/utility/inputStreamStringProxyAdapter.hpp
|
|
@@ -25,7 +25,7 @@
|
|
#define VMIME_UTILITY_INPUTSTREAMSTRINGPROXYADAPTER_HPP_INCLUDED
|
|
|
|
|
|
-#include "vmime/utility/inputStream.hpp"
|
|
+#include "vmime/utility/seekableInputStream.hpp"
|
|
|
|
|
|
namespace vmime {
|
|
@@ -38,7 +38,7 @@ class stringProxy;
|
|
/** An adapter class for stringProxy input.
|
|
*/
|
|
|
|
-class inputStreamStringProxyAdapter : public inputStream
|
|
+class inputStreamStringProxyAdapter : public seekableInputStream
|
|
{
|
|
public:
|
|
|
|
@@ -50,6 +50,8 @@ public:
|
|
void reset();
|
|
size_type read(value_type* const data, const size_type count);
|
|
size_type skip(const size_type count);
|
|
+ size_type getPosition() const;
|
|
+ void seek(const size_type pos);
|
|
|
|
private:
|
|
|
|
diff --git a/vmime/utility/parserInputStreamAdapter.hpp b/vmime/utility/parserInputStreamAdapter.hpp
|
|
new file mode 100644
|
|
index 0000000..c24fa44
|
|
--- /dev/null
|
|
+++ b/vmime/utility/parserInputStreamAdapter.hpp
|
|
@@ -0,0 +1,173 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#ifndef VMIME_UTILITY_PARSERINPUTSTREAMADAPTER_HPP_INCLUDED
|
|
+#define VMIME_UTILITY_PARSERINPUTSTREAMADAPTER_HPP_INCLUDED
|
|
+
|
|
+
|
|
+#include "vmime/utility/seekableInputStream.hpp"
|
|
+
|
|
+#include <cstring>
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+/** An adapter class used for parsing from an input stream.
|
|
+ */
|
|
+
|
|
+class parserInputStreamAdapter : public seekableInputStream
|
|
+{
|
|
+public:
|
|
+
|
|
+ /** @param is input stream to wrap
|
|
+ */
|
|
+ parserInputStreamAdapter(ref <seekableInputStream> inputStream);
|
|
+
|
|
+ ref <seekableInputStream> getUnderlyingStream();
|
|
+
|
|
+ bool eof() const;
|
|
+ void reset();
|
|
+ size_type read(value_type* const data, const size_type count);
|
|
+
|
|
+ void seek(const size_type pos)
|
|
+ {
|
|
+ m_stream->seek(pos);
|
|
+ }
|
|
+
|
|
+ size_type skip(const size_type count)
|
|
+ {
|
|
+ return m_stream->skip(count);
|
|
+ }
|
|
+
|
|
+ size_type getPosition() const
|
|
+ {
|
|
+ return m_stream->getPosition();
|
|
+ }
|
|
+
|
|
+ /** Get the byte at the current position without updating the
|
|
+ * current position.
|
|
+ *
|
|
+ * @return byte at the current position
|
|
+ */
|
|
+ value_type peekByte() const
|
|
+ {
|
|
+ const size_type initialPos = m_stream->getPosition();
|
|
+
|
|
+ try
|
|
+ {
|
|
+ value_type buffer[1];
|
|
+ const size_type readBytes = m_stream->read(buffer, 1);
|
|
+
|
|
+ m_stream->seek(initialPos);
|
|
+
|
|
+ return (readBytes == 1 ? buffer[0] : 0);
|
|
+ }
|
|
+ catch (...)
|
|
+ {
|
|
+ m_stream->seek(initialPos);
|
|
+ throw;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /** Get the byte at the current position and advance current
|
|
+ * position by one byte.
|
|
+ *
|
|
+ * @return byte at the current position
|
|
+ */
|
|
+ value_type getByte()
|
|
+ {
|
|
+ value_type buffer[1];
|
|
+ const size_type readBytes = m_stream->read(buffer, 1);
|
|
+
|
|
+ return (readBytes == 1 ? buffer[0] : 0);
|
|
+ }
|
|
+
|
|
+ /** Check whether the bytes following the current position match
|
|
+ * the specified bytes. Position is not updated.
|
|
+ *
|
|
+ * @param bytes bytes to compare
|
|
+ * @param length number of bytes
|
|
+ * @return true if the next bytes match the pattern, false otherwise
|
|
+ */
|
|
+ bool matchBytes(const value_type* bytes, const size_type length) const
|
|
+ {
|
|
+ const size_type initialPos = m_stream->getPosition();
|
|
+
|
|
+ try
|
|
+ {
|
|
+ value_type buffer[32];
|
|
+ const size_type readBytes = m_stream->read(buffer, length);
|
|
+
|
|
+ m_stream->seek(initialPos);
|
|
+
|
|
+ return readBytes == length &&
|
|
+ ::memcmp(bytes, buffer, length) == 0;
|
|
+ }
|
|
+ catch (...)
|
|
+ {
|
|
+ m_stream->seek(initialPos);
|
|
+ throw;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ const string extract(const size_type begin, const size_type end) const;
|
|
+
|
|
+ /** Skips bytes matching a predicate from the current position.
|
|
+ * The current position is updated to the next following byte
|
|
+ * which does not match the predicate.
|
|
+ *
|
|
+ * @param pred predicate
|
|
+ * @param endPosition stop at this position (or at end of the stream,
|
|
+ * whichever comes first)
|
|
+ * @return number of bytes skipped
|
|
+ */
|
|
+ template <typename PREDICATE>
|
|
+ size_type skipIf(PREDICATE pred, const size_type endPosition)
|
|
+ {
|
|
+ const size_type initialPos = getPosition();
|
|
+ size_type pos = initialPos;
|
|
+
|
|
+ while (!m_stream->eof() && pos < endPosition && pred(getByte()))
|
|
+ ++pos;
|
|
+
|
|
+ m_stream->seek(pos);
|
|
+
|
|
+ return pos - initialPos;
|
|
+ }
|
|
+
|
|
+ size_type findNext(const std::string& token, const size_type startPosition = 0);
|
|
+
|
|
+private:
|
|
+
|
|
+ mutable ref <seekableInputStream> m_stream;
|
|
+};
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
+
|
|
+#endif // VMIME_UTILITY_PARSERINPUTSTREAMADAPTER_HPP_INCLUDED
|
|
+
|
|
diff --git a/vmime/utility/seekableInputStream.hpp b/vmime/utility/seekableInputStream.hpp
|
|
new file mode 100644
|
|
index 0000000..c2ab1bb
|
|
--- /dev/null
|
|
+++ b/vmime/utility/seekableInputStream.hpp
|
|
@@ -0,0 +1,64 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#ifndef VMIME_UTILITY_SEEKABLEINPUTSTREAM_HPP_INCLUDED
|
|
+#define VMIME_UTILITY_SEEKABLEINPUTSTREAM_HPP_INCLUDED
|
|
+
|
|
+
|
|
+#include "vmime/utility/inputStream.hpp"
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+/** An input stream that allows seeking within the input.
|
|
+ */
|
|
+
|
|
+class seekableInputStream : public inputStream
|
|
+{
|
|
+public:
|
|
+
|
|
+ /** Returns the current position in this stream.
|
|
+ *
|
|
+ * @return the offset from the beginning of the stream, in bytes,
|
|
+ * at which the next read occurs
|
|
+ */
|
|
+ virtual size_type getPosition() const = 0;
|
|
+
|
|
+ /** Sets the position, measured from the beginning of this stream,
|
|
+ * at which the next read occurs.
|
|
+ *
|
|
+ * @param pos the offset position, measured in bytes from the
|
|
+ * beginning of the stream, at which to set the stream pointer.
|
|
+ */
|
|
+ virtual void seek(const size_type pos) = 0;
|
|
+};
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
+
|
|
+#endif // VMIME_UTILITY_SEEKABLEINPUTSTREAM_HPP_INCLUDED
|
|
+
|
|
diff --git a/vmime/utility/seekableInputStreamRegionAdapter.hpp b/vmime/utility/seekableInputStreamRegionAdapter.hpp
|
|
new file mode 100644
|
|
index 0000000..5ebccc6
|
|
--- /dev/null
|
|
+++ b/vmime/utility/seekableInputStreamRegionAdapter.hpp
|
|
@@ -0,0 +1,71 @@
|
|
+//
|
|
+// VMime library (http://www.vmime.org)
|
|
+// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
|
+//
|
|
+// This program is free software; you can redistribute it and/or
|
|
+// modify it under the terms of the GNU General Public License as
|
|
+// published by the Free Software Foundation; either version 3 of
|
|
+// the License, or (at your option) any later version.
|
|
+//
|
|
+// This program is distributed in the hope that it will be useful,
|
|
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+// General Public License for more details.
|
|
+//
|
|
+// You should have received a copy of the GNU General Public License along
|
|
+// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+//
|
|
+// Linking this library statically or dynamically with other modules is making
|
|
+// a combined work based on this library. Thus, the terms and conditions of
|
|
+// the GNU General Public License cover the whole combination.
|
|
+//
|
|
+
|
|
+#ifndef VMIME_UTILITY_SEEKABLEINPUTSTREAMREGIONADAPTER_HPP_INCLUDED
|
|
+#define VMIME_UTILITY_SEEKABLEINPUTSTREAMREGIONADAPTER_HPP_INCLUDED
|
|
+
|
|
+
|
|
+#include "vmime/utility/seekableInputStream.hpp"
|
|
+
|
|
+
|
|
+namespace vmime {
|
|
+namespace utility {
|
|
+
|
|
+
|
|
+/** An adapter for reading a limited region of a seekable input stream.
|
|
+ */
|
|
+
|
|
+class seekableInputStreamRegionAdapter : public seekableInputStream
|
|
+{
|
|
+public:
|
|
+
|
|
+ /** Creates a new adapter for a seekableInputStream.
|
|
+ *
|
|
+ * @param stream source stream
|
|
+ * @param begin start position in source stream
|
|
+ * @param length region length in source stream
|
|
+ */
|
|
+ seekableInputStreamRegionAdapter(ref <seekableInputStream> stream,
|
|
+ const size_type begin, const size_type length);
|
|
+
|
|
+ bool eof() const;
|
|
+ void reset();
|
|
+ size_type read(value_type* const data, const size_type count);
|
|
+ size_type skip(const size_type count);
|
|
+ size_type getPosition() const;
|
|
+ void seek(const size_type pos);
|
|
+
|
|
+private:
|
|
+
|
|
+ ref <seekableInputStream> m_stream;
|
|
+ size_type m_begin;
|
|
+ size_type m_length;
|
|
+};
|
|
+
|
|
+
|
|
+} // utility
|
|
+} // vmime
|
|
+
|
|
+
|
|
+#endif // VMIME_UTILITY_SEEKABLEINPUTSTREAMREGIONADAPTER_HPP_INCLUDED
|
|
+
|
|
diff --git a/vmime/utility/stream.hpp b/vmime/utility/stream.hpp
|
|
index 566ab9d..78be827 100644
|
|
--- a/vmime/utility/stream.hpp
|
|
+++ b/vmime/utility/stream.hpp
|
|
@@ -54,6 +54,10 @@ public:
|
|
*/
|
|
typedef string::size_type size_type;
|
|
|
|
+ /** Constant value with the greatest possible value for an element of type size_type.
|
|
+ */
|
|
+ static const size_type npos;
|
|
+
|
|
/** Return the preferred maximum block size when reading
|
|
* from or writing to this stream.
|
|
*
|
|
diff --git a/vmime/utility/streamUtils.hpp b/vmime/utility/streamUtils.hpp
|
|
index cdf70aa..87c8fc5 100644
|
|
--- a/vmime/utility/streamUtils.hpp
|
|
+++ b/vmime/utility/streamUtils.hpp
|
|
@@ -45,6 +45,19 @@ namespace utility {
|
|
stream::size_type bufferedStreamCopy(inputStream& is, outputStream& os);
|
|
|
|
/** Copy data from one stream into another stream using a buffered method
|
|
+ * and copying only a specified range of data.
|
|
+ *
|
|
+ * @param is input stream (source data)
|
|
+ * @param os output stream (destination for data)
|
|
+ * @param start number of bytes to ignore before starting copying
|
|
+ * @param length maximum number of bytes to copy
|
|
+ * @return number of bytes copied
|
|
+ */
|
|
+
|
|
+stream::size_type bufferedStreamCopyRange(inputStream& is, outputStream& os,
|
|
+ const stream::size_type start, const stream::size_type length);
|
|
+
|
|
+/** Copy data from one stream into another stream using a buffered method
|
|
* and notify progress state of the operation.
|
|
*
|
|
* @param is input stream (source data)
|
|
diff --git a/vmime/word.hpp b/vmime/word.hpp
|
|
index ad848ec..492aab5 100644
|
|
--- a/vmime/word.hpp
|
|
+++ b/vmime/word.hpp
|
|
@@ -128,21 +128,52 @@ public:
|
|
#endif
|
|
|
|
|
|
- using component::parse;
|
|
- using component::generate;
|
|
+protected:
|
|
|
|
- void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
+ void parseImpl
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition = NULL);
|
|
|
|
- void generate(utility::outputStream& os, const string::size_type maxLineLength, const string::size_type curLinePos, string::size_type* newLinePos, const int flags, generatorState* state) const;
|
|
+ void generateImpl
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength = lineLengthLimits::infinite,
|
|
+ const string::size_type curLinePos = 0,
|
|
+ string::size_type* newLinePos = NULL) const;
|
|
|
|
- const std::vector <ref <const component> > getChildComponents() const;
|
|
+public:
|
|
|
|
-private:
|
|
+ using component::generate;
|
|
|
|
- static ref <word> parseNext(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition, bool prevIsEncoded, bool* isEncoded, bool isFirst);
|
|
+#ifndef VMIME_BUILDING_DOC
|
|
+ void generate
|
|
+ (utility::outputStream& os,
|
|
+ const string::size_type maxLineLength,
|
|
+ const string::size_type curLinePos,
|
|
+ string::size_type* newLinePos,
|
|
+ const int flags,
|
|
+ generatorState* state) const;
|
|
+#endif
|
|
+
|
|
+ const std::vector <ref <component> > getChildComponents();
|
|
+
|
|
+private:
|
|
|
|
- static const std::vector <ref <word> > parseMultiple(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition);
|
|
+ static ref <word> parseNext
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition,
|
|
+ bool prevIsEncoded,
|
|
+ bool* isEncoded,
|
|
+ bool isFirst);
|
|
+
|
|
+ static const std::vector <ref <word> > parseMultiple
|
|
+ (const string& buffer,
|
|
+ const string::size_type position,
|
|
+ const string::size_type end,
|
|
+ string::size_type* newPosition);
|
|
|
|
|
|
// The "m_buffer" of this word holds the data, and this data is encoded
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From 2e05e574fde890c7ec6dd9f3930d06b1b492ea80 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Fri, 27 Apr 2012 08:34:26 +0200
|
|
Subject: [PATCH 38/39] Fixed duplicate file reference (thanks to Enes Albay).
|
|
|
|
|
|
diff --git a/SConstruct b/SConstruct
|
|
index 2690172..1f3c7c9 100644
|
|
--- a/SConstruct
|
|
+++ b/SConstruct
|
|
@@ -137,7 +137,6 @@ libvmime_sources = [
|
|
'utility/childProcess.hpp',
|
|
'utility/file.hpp',
|
|
'utility/datetimeUtils.cpp', 'utility/datetimeUtils.hpp',
|
|
- 'utility/filteredStream.cpp', 'utility/filteredStream.hpp',
|
|
'utility/path.cpp', 'utility/path.hpp',
|
|
'utility/progressListener.cpp', 'utility/progressListener.hpp',
|
|
'utility/random.cpp', 'utility/random.hpp',
|
|
--
|
|
1.7.10.4
|
|
|
|
|
|
From 799629fd8b21a716f3e3abc6e6a5264555470d85 Mon Sep 17 00:00:00 2001
|
|
From: Vincent Richard <vincent@vincent-richard.net>
|
|
Date: Fri, 6 Jul 2012 18:45:02 +0200
|
|
Subject: [PATCH 39/39] Fixed issue #10.
|
|
|
|
|
|
diff --git a/src/net/imap/IMAPMessage.cpp b/src/net/imap/IMAPMessage.cpp
|
|
index 702d5f2..8006920 100644
|
|
--- a/src/net/imap/IMAPMessage.cpp
|
|
+++ b/src/net/imap/IMAPMessage.cpp
|
|
@@ -279,8 +279,6 @@ void IMAPMessage::extract(ref <const part> p, utility::outputStream& os,
|
|
{
|
|
if (headerOnly)
|
|
command << "HEADER";
|
|
- else
|
|
- command << "TEXT";
|
|
}
|
|
else
|
|
{
|
|
--
|
|
1.7.10.4
|
|
|