aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/encoding.cpp52
-rw-r--r--src/utility/encoder/qpEncoder.cpp9
-rw-r--r--tests/parser/bodyPartTest.cpp24
-rw-r--r--vmime/encoding.hpp16
4 files changed, 91 insertions, 10 deletions
diff --git a/src/encoding.cpp b/src/encoding.cpp
index 0919d44c..b4e79db7 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 aa95022f..ab8db2e4 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 e1d47a36..9d51262a 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 ba78081a..42f5246d 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.
*