diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/vmime/parameter.cpp | 8 | ||||
-rw-r--r-- | src/vmime/word.cpp | 54 | ||||
-rw-r--r-- | src/vmime/word.hpp | 16 | ||||
-rw-r--r-- | src/vmime/wordEncoder.cpp | 7 | ||||
-rw-r--r-- | src/vmime/wordEncoder.hpp | 4 |
5 files changed, 78 insertions, 11 deletions
diff --git a/src/vmime/parameter.cpp b/src/vmime/parameter.cpp index 45e68ad6..8773e857 100644 --- a/src/vmime/parameter.cpp +++ b/src/vmime/parameter.cpp @@ -134,6 +134,7 @@ void parameter::parse(const parsingContext& ctx, const std::vector <valueChunk>& bool foundCharsetChunk = false; charset ch(charsets::US_ASCII); + string lang; std::ostringstream value; value.imbue(std::locale::classic()); @@ -170,7 +171,9 @@ void parameter::parse(const parsingContext& ctx, const std::vector <valueChunk>& if (q != string::npos) { - // Ignore language + // Extract language + lang = chunk.data.substr(pos, q - pos); + ++q; pos = q; } @@ -268,6 +271,7 @@ void parameter::parse(const parsingContext& ctx, const std::vector <valueChunk>& m_value->setBuffer(value.str()); m_value->setCharset(ch); + m_value->setLanguage(lang); } @@ -372,7 +376,7 @@ void parameter::generateImpl const bool alwaysEncode = m_value->getCharset().getRecommendedEncoding(recommendedEnc); bool extended = alwaysEncode; - if ((needQuotedPrintable || cutValue) && + if ((needQuotedPrintable || cutValue || !m_value->getLanguage().empty()) && genMode != generationContext::PARAMETER_VALUE_NO_ENCODING) { // Send the name in quoted-printable, so outlook express et.al. diff --git a/src/vmime/word.cpp b/src/vmime/word.cpp index 7944fc77..2229857c 100644 --- a/src/vmime/word.cpp +++ b/src/vmime/word.cpp @@ -48,7 +48,8 @@ word::word() word::word(const word& w) - : headerFieldValue(), m_buffer(w.m_buffer), m_charset(w.m_charset) + : headerFieldValue(), m_buffer(w.m_buffer), + m_charset(w.m_charset), m_lang(w.m_lang) { } @@ -65,6 +66,12 @@ word::word(const string& buffer, const charset& charset) } +word::word(const string& buffer, const charset& charset, const string& lang) + : m_buffer(buffer), m_charset(charset), m_lang(lang) +{ +} + + shared_ptr <word> word::parseNext (const parsingContext& ctx, const string& buffer, const size_t position, const size_t end, size_t* newPosition, @@ -296,6 +303,21 @@ void word::parseImpl if (theEncoder) { + // Extract charset and language + const string charsetAndLang(charsetPos, charsetEnd); + const string::size_type asteriskPos = charsetAndLang.find('*'); + + if (asteriskPos != string::npos) + { + m_charset = charset(string(charsetAndLang.begin(), charsetAndLang.begin() + asteriskPos)); + m_lang = string(charsetAndLang.begin() + asteriskPos + 1, charsetAndLang.end()); + } + else + { + m_charset = charset(charsetAndLang); + m_lang.clear(); + } + // Decode text string decodedBuffer; @@ -306,7 +328,6 @@ void word::parseImpl delete (theEncoder); m_buffer = decodedBuffer; - m_charset = charset(string(charsetPos, charsetEnd)); setParsedBounds(position, p - buffer.begin()); @@ -358,7 +379,7 @@ void word::generate(const generationContext& ctx, utility::outputStream& os, else if ((flags & text::FORCE_ENCODING) != 0) encodingNeeded = true; else // auto-detect - encodingNeeded = wordEncoder::isEncodingNeeded(ctx, m_buffer, m_charset); + encodingNeeded = wordEncoder::isEncodingNeeded(ctx, m_buffer, m_charset, m_lang); // If text does not need to be encoded, quote the buffer (no folding is performed). if (!encodingNeeded && @@ -600,8 +621,12 @@ void word::generate(const generationContext& ctx, utility::outputStream& os, wordEncoder wordEnc(m_buffer, m_charset); - const string wordStart("=?" + m_charset.getName() + "?" + - (wordEnc.getEncoding() == wordEncoder::ENCODING_B64 ? 'B' : 'Q') + "?"); + const string wordStart("=?" + + m_charset.getName() + + (m_lang.empty() ? "" : string("*") + m_lang) + + "?" + + (wordEnc.getEncoding() == wordEncoder::ENCODING_B64 ? 'B' : 'Q') + + "?"); const string wordEnd("?="); const size_t minWordLength = wordStart.length() + wordEnd.length(); @@ -690,6 +715,7 @@ word& word::operator=(const word& w) { m_buffer = w.m_buffer; m_charset = w.m_charset; + m_lang = w.m_lang; return (*this); } @@ -698,6 +724,7 @@ word& word::operator=(const string& s) { m_buffer = s; m_charset = charset::getLocalCharset(); + m_lang.clear(); return (*this); } @@ -708,18 +735,19 @@ void word::copyFrom(const component& other) m_buffer = w.m_buffer; m_charset = w.m_charset; + m_lang = w.m_lang; } bool word::operator==(const word& w) const { - return (m_charset == w.m_charset && m_buffer == w.m_buffer); + return (m_charset == w.m_charset && m_buffer == w.m_buffer && m_lang == w.m_lang); } bool word::operator!=(const word& w) const { - return (m_charset != w.m_charset || m_buffer != w.m_buffer); + return (m_charset != w.m_charset || m_buffer != w.m_buffer || m_lang != w.m_lang); } @@ -769,6 +797,18 @@ void word::setCharset(const charset& ch) } +const string word::getLanguage() const +{ + return m_lang; +} + + +void word::setLanguage(const string& lang) +{ + m_lang = lang; +} + + const string& word::getBuffer() const { return (m_buffer); diff --git a/src/vmime/word.hpp b/src/vmime/word.hpp index 4122228d..0e60225e 100644 --- a/src/vmime/word.hpp +++ b/src/vmime/word.hpp @@ -48,6 +48,7 @@ public: word(const word& w); word(const string& buffer); // Defaults to local charset word(const string& buffer, const charset& charset); + word(const string& buffer, const charset& charset, const string& lang); /** Return the raw data for this encoded word. * @@ -85,6 +86,20 @@ public: */ void setCharset(const charset& ch); + /** Return the language used in this word (optional). + * If not specified, the value is empty. + * + * @return language tag for this word, in the format specified + * by RFC-1766 + */ + const string getLanguage() const; + + /** Set the language used in this word (optional). + * + * @param lang language tag, in the format specified by RFC-1766 + */ + void setLanguage(const string& lang); + /** Returns whether two words actually represent the same text, * regardless of their charset. * @@ -194,6 +209,7 @@ private: // in the specified "m_charset". string m_buffer; charset m_charset; + string m_lang; }; diff --git a/src/vmime/wordEncoder.cpp b/src/vmime/wordEncoder.cpp index 421a9ecd..b40f5371 100644 --- a/src/vmime/wordEncoder.cpp +++ b/src/vmime/wordEncoder.cpp @@ -226,7 +226,8 @@ wordEncoder::Encoding wordEncoder::getEncoding() const // static bool wordEncoder::isEncodingNeeded - (const generationContext& ctx, const string& buffer, const charset& charset) + (const generationContext& ctx, const string& buffer, + const charset& charset, const string& lang) { if (!ctx.getInternationalizedEmailSupport()) { @@ -250,6 +251,10 @@ bool wordEncoder::isEncodingNeeded if (buffer.find("=?") != string::npos || buffer.find("?=") != string::npos) return true; + // If a language is specified, force encoding + if (!lang.empty()) + return true; + return false; } diff --git a/src/vmime/wordEncoder.hpp b/src/vmime/wordEncoder.hpp index 6f652fa2..8abd3d3c 100644 --- a/src/vmime/wordEncoder.hpp +++ b/src/vmime/wordEncoder.hpp @@ -78,9 +78,11 @@ public: * @param ctx generation context * @param buffer buffer to analyze * @param charset charset of the buffer + * @param lang language code, in the format specified by RFC-1766 * @return true if encoding is needed, false otherwise. */ - static bool isEncodingNeeded(const generationContext& ctx, const string& buffer, const charset& charset); + static bool isEncodingNeeded(const generationContext& ctx, const string& buffer, + const charset& charset, const string& lang); /** Guess the best RFC-2047 encoding to use for the specified buffer. * |