// // VMime library (http://www.vmime.org) // Copyright (C) 2002-2005 Vincent Richard // // 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 2 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/text.hpp" #include "vmime/parserHelpers.hpp" namespace vmime { text::text() { } text::text(const text& t) : headerFieldValue() { copyFrom(t); } text::text(const string& t, const charset& ch) { createFromString(t, ch); } text::text(const string& t) { createFromString(t, charset::getLocaleCharset()); } text::text(const word& w) { appendWord(vmime::create (w)); } text::~text() { removeAllWords(); } void text::parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition) { removeAllWords(); string::size_type newPos; const std::vector > words = word::parseMultiple(buffer, position, end, &newPos); copy_vector(words, m_words); setParsedBounds(position, newPos); if (newPosition) *newPosition = newPos; } void text::generate(utility::outputStream& os, const string::size_type maxLineLength, const string::size_type curLinePos, string::size_type* newLinePos) const { encodeAndFold(os, maxLineLength, curLinePos, newLinePos, 0); } #if VMIME_WIDE_CHAR_SUPPORT const wstring text::getDecodedText() const { wstring out; for (std::vector >::const_iterator i = m_words.begin() ; i != m_words.end() ; ++i) out += (*i)->getDecodedText(); return (out); } #endif void text::copyFrom(const component& other) { const text& t = dynamic_cast (other); removeAllWords(); for (std::vector >::const_iterator i = t.m_words.begin() ; i != t.m_words.end() ; ++i) m_words.push_back(vmime::create (**i)); } text& text::operator=(const component& other) { copyFrom(other); return (*this); } text& text::operator=(const text& other) { copyFrom(other); return (*this); } const bool text::operator==(const text& t) const { if (getWordCount() == t.getWordCount()) { bool equal = true; std::vector >::const_iterator i = m_words.begin(); std::vector >::const_iterator j = t.m_words.begin(); for ( ; equal && i != m_words.end() ; ++i, ++j) equal = (**i == **j); return (equal); } return (false); } const bool text::operator!=(const text& t) const { return !(*this == t); } const string text::getConvertedText(const charset& dest) const { string out; for (std::vector >::const_iterator i = m_words.begin() ; i != m_words.end() ; ++i) out += (*i)->getConvertedText(dest); return (out); } void text::appendWord(ref w) { m_words.push_back(w); } void text::insertWordBefore(const int pos, ref w) { m_words.insert(m_words.begin() + pos, w); } void text::insertWordAfter(const int pos, ref w) { m_words.insert(m_words.begin() + pos + 1, w); } void text::removeWord(const int pos) { const std::vector >::iterator it = m_words.begin() + pos; m_words.erase(it); } void text::removeAllWords() { m_words.clear(); } const int text::getWordCount() const { return (m_words.size()); } const bool text::isEmpty() const { return (m_words.empty()); } const ref text::getWordAt(const int pos) { return (m_words[pos]); } const ref text::getWordAt(const int pos) const { return (m_words[pos]); } const std::vector > text::getWordList() const { std::vector > list; list.reserve(m_words.size()); for (std::vector >::const_iterator it = m_words.begin() ; it != m_words.end() ; ++it) { list.push_back(*it); } return (list); } const std::vector > text::getWordList() { return (m_words); } ref text::clone() const { return vmime::create (*this); } ref text::newFromString(const string& in, const charset& ch) { ref t = vmime::create (); t->createFromString(in, ch); return t; } void text::createFromString(const string& in, const charset& ch) { const string::const_iterator end = in.end(); string::const_iterator p = in.begin(); string::const_iterator start = in.begin(); bool is8bit = false; // is the current word 8-bit? bool prevIs8bit = false; // is previous word 8-bit? unsigned int count = 0; // total number of words removeAllWords(); for ( ; ; ) { if (p == end || parserHelpers::isSpace(*p)) { if (p != end) ++p; if (is8bit) { if (count && prevIs8bit) { // No need to create a new encoded word, just append // the current word to the previous one. ref w = getWordAt(getWordCount() - 1); w->getBuffer() += string(start, p); } else { appendWord(vmime::create (string(start, p), ch)); prevIs8bit = true; ++count; } } else { if (count && !prevIs8bit) { ref w = getWordAt(getWordCount() - 1); w->getBuffer() += string(start, p); } else { appendWord(vmime::create (string(start, p), charset(charsets::US_ASCII))); prevIs8bit = false; ++count; } } if (p == end) break; is8bit = false; start = p; } else if (!parserHelpers::isAscii(*p)) { is8bit = true; ++p; } else { ++p; } } } void text::encodeAndFold(utility::outputStream& os, const string::size_type maxLineLength, const string::size_type firstLineOffset, string::size_type* lastLineLength, const int flags) const { string::size_type curLineLength = firstLineOffset; for (int wi = 0 ; wi < getWordCount() ; ++wi) { getWordAt(wi)->generate(os, maxLineLength, curLineLength, &curLineLength, flags, (wi == 0)); } if (lastLineLength) *lastLineLength = curLineLength; } ref text::decodeAndUnfold(const string& in) { ref t = vmime::create (); decodeAndUnfold(in, t.get()); return t; } text* text::decodeAndUnfold(const string& in, text* generateInExisting) { text* out = (generateInExisting != NULL) ? generateInExisting : new text(); out->removeAllWords(); const std::vector > words = word::parseMultiple(in, 0, in.length(), NULL); copy_vector(words, out->m_words); return (out); } const std::vector > text::getChildComponents() const { std::vector > list; copy_vector(m_words, list); return (list); } const string text::getWholeBuffer() const { string res; for (std::vector >::const_iterator it = m_words.begin() ; it != m_words.end() ; ++it) { res += (*it)->getBuffer(); } return res; } } // vmime