aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/body.cpp35
-rw-r--r--src/contentHandler.cpp333
-rw-r--r--src/defaultAttachment.cpp22
-rw-r--r--src/emptyContentHandler.cpp75
-rw-r--r--src/fileAttachment.cpp6
-rw-r--r--src/htmlTextPart.cpp50
-rw-r--r--src/plainTextPart.cpp24
-rw-r--r--src/streamContentHandler.cpp206
-rw-r--r--src/stringContentHandler.cpp192
9 files changed, 570 insertions, 373 deletions
diff --git a/src/body.cpp b/src/body.cpp
index 85e1f4f7..74c3a8e8 100644
--- a/src/body.cpp
+++ b/src/body.cpp
@@ -28,25 +28,31 @@
#include "vmime/parserHelpers.hpp"
+#include "vmime/emptyContentHandler.hpp"
+#include "vmime/stringContentHandler.hpp"
+
namespace vmime
{
body::body()
- : m_part(NULL), m_header(NULL)
+ : m_contents(new emptyContentHandler()), m_part(NULL), m_header(NULL)
{
}
body::body(bodyPart* parentPart)
- : m_part(parentPart), m_header(parentPart != NULL ? parentPart->getHeader() : NULL)
+ : m_contents(new emptyContentHandler()),
+ m_part(parentPart), m_header(parentPart != NULL ? parentPart->getHeader() : NULL)
{
}
body::~body()
{
+ delete (m_contents);
+
removeAllParts();
}
@@ -190,7 +196,7 @@ void body::parse(const string& buffer, const string::size_type position,
pos = buffer.find(boundarySep, partStart);
}
- m_contents.setData("");
+ setContentsImpl(emptyContentHandler());
if (partStart < end)
m_epilogText = string(buffer.begin() + partStart, buffer.begin() + end);
@@ -199,7 +205,7 @@ void body::parse(const string& buffer, const string::size_type position,
else
{
// Extract the (encoded) contents
- m_contents.setData(buffer, position, end, getEncoding());
+ setContentsImpl(stringContentHandler(buffer, position, end, getEncoding()));
}
setParsedBounds(position, end);
@@ -298,7 +304,7 @@ void body::generate(utility::outputStream& os, const string::size_type maxLineLe
else
{
// Generate the contents
- m_contents.generate(os, getEncoding(), maxLineLength);
+ m_contents->generate(os, getEncoding(), maxLineLength);
}
}
@@ -471,7 +477,7 @@ void body::copyFrom(const component& other)
m_prologText = bdy.m_prologText;
m_epilogText = bdy.m_epilogText;
- m_contents = bdy.m_contents;
+ setContentsImpl(*bdy.m_contents);
removeAllParts();
@@ -519,19 +525,13 @@ void body::setEpilogText(const string& epilogText)
const contentHandler& body::getContents() const
{
- return (m_contents);
-}
-
-
-contentHandler& body::getContents()
-{
- return (m_contents);
+ return (*m_contents);
}
void body::setContents(const contentHandler& contents)
{
- m_contents = contents;
+ setContentsImpl(contents);
}
@@ -716,4 +716,11 @@ const std::vector <const component*> body::getChildComponents() const
}
+void body::setContentsImpl(const contentHandler& cts)
+{
+ delete (m_contents);
+ m_contents = cts.clone();
+}
+
+
} // vmime
diff --git a/src/contentHandler.cpp b/src/contentHandler.cpp
index 295df165..ced4cd3e 100644
--- a/src/contentHandler.cpp
+++ b/src/contentHandler.cpp
@@ -28,342 +28,9 @@ namespace vmime
const encoding contentHandler::NO_ENCODING(encodingTypes::BINARY);
-contentHandler::contentHandler()
- : m_type(TYPE_NONE), m_encoding(NO_ENCODING), m_ownedStream(NULL), m_stream(NULL)
-{
-}
-
-
-contentHandler::contentHandler(const string& buffer, const vmime::encoding& enc)
- : m_type(TYPE_STRING), m_encoding(enc), m_string(buffer),
- m_ownedStream(NULL), m_stream(NULL)
-{
-}
-
-
contentHandler::~contentHandler()
{
}
-contentHandler::contentHandler(const contentHandler& cts)
- : m_type(cts.m_type), m_encoding(cts.m_encoding), m_string(cts.m_string),
- m_ownedStream(const_cast <utility::smart_ptr <utility::inputStream>&>(cts.m_ownedStream)),
- m_stream(cts.m_stream), m_length(cts.m_length)
-{
-}
-
-
-contentHandler& contentHandler::operator=(const contentHandler& cts)
-{
- m_type = cts.m_type;
- m_encoding = cts.m_encoding;
-
- m_string = cts.m_string;
-
- m_ownedStream = const_cast <utility::smart_ptr <utility::inputStream>&>(cts.m_ownedStream);
- m_stream = cts.m_stream;
- m_length = cts.m_length;
-
- return (*this);
-}
-
-
-void contentHandler::setData(const utility::stringProxy& str, const vmime::encoding& enc)
-{
- m_type = TYPE_STRING;
- m_encoding = enc;
-
- m_string = str;
-
- m_ownedStream = NULL;
- m_stream = NULL;
-}
-
-
-void contentHandler::setData(const string& buffer, const vmime::encoding& enc)
-{
- m_type = TYPE_STRING;
- m_encoding = enc;
-
- m_string.set(buffer);
-
- m_ownedStream = NULL;
- m_stream = NULL;
-}
-
-
-void contentHandler::setData(const string& buffer, const string::size_type start,
- const string::size_type end, const vmime::encoding& enc)
-{
- m_type = TYPE_STRING;
- m_encoding = enc;
-
- m_string.set(buffer, start, end);
-
- m_ownedStream = NULL;
- m_stream = NULL;
-}
-
-
-void contentHandler::setData(utility::inputStream* is, const utility::stream::size_type length,
- const bool own, const vmime::encoding& enc)
-{
- m_type = TYPE_STREAM;
- m_encoding = enc;
-
- m_length = length;
-
- if (own)
- {
- m_ownedStream = is;
- m_stream = NULL;
- }
- else
- {
- m_ownedStream = NULL;
- m_stream = is;
- }
-
- m_string.detach();
-}
-
-
-contentHandler& contentHandler::operator=(const string& buffer)
-{
- setData(buffer, NO_ENCODING);
- return (*this);
-}
-
-
-void contentHandler::generate(utility::outputStream& os, const vmime::encoding& enc,
- const string::size_type maxLineLength) const
-{
- if (m_type == TYPE_NONE)
- return;
-
- // Managed data is already encoded
- if (isEncoded())
- {
- // The data is already encoded but the encoding specified for
- // the generation is different from the current one. We need
- // to re-encode data: decode from input buffer to temporary
- // buffer, and then re-encode to output stream...
- if (m_encoding != enc)
- {
- utility::auto_ptr <encoder> theDecoder(m_encoding.getEncoder());
- utility::auto_ptr <encoder> theEncoder(enc.getEncoder());
-
- theEncoder->getProperties()["maxlinelength"] = maxLineLength;
-
- switch (m_type)
- {
- default:
- {
- // No data
- break;
- }
- case TYPE_STRING:
- {
- utility::inputStreamStringProxyAdapter in(m_string);
-
- std::ostringstream oss;
- utility::outputStreamAdapter tempOut(oss);
-
- theDecoder->decode(in, tempOut);
-
- string str = oss.str();
- utility::inputStreamStringAdapter tempIn(str);
-
- theEncoder->encode(tempIn, os);
-
- break;
- }
- case TYPE_STREAM:
- {
- utility::inputStream& in = const_cast <utility::inputStream&>
- (*(m_stream ? m_stream : m_ownedStream.ptr()));
-
- in.reset(); // may not work...
-
- std::ostringstream oss;
- utility::outputStreamAdapter tempOut(oss);
-
- theDecoder->decode(in, tempOut);
-
- string str = oss.str();
- utility::inputStreamStringAdapter tempIn(str);
-
- theEncoder->encode(tempIn, os);
-
- break;
- }
-
- }
- }
- // No encoding to perform
- else
- {
- switch (m_type)
- {
- default:
- {
- // No data
- break;
- }
- case TYPE_STRING:
- {
- m_string.extract(os);
- break;
- }
- case TYPE_STREAM:
- {
- utility::inputStream& in = const_cast <utility::inputStream&>
- (*(m_stream ? m_stream : m_ownedStream.ptr()));
-
- in.reset(); // may not work...
-
- utility::bufferedStreamCopy(in, os);
- break;
- }
-
- }
- }
- }
- // Need to encode data before
- else
- {
- utility::auto_ptr <encoder> theEncoder(enc.getEncoder());
- theEncoder->getProperties()["maxlinelength"] = maxLineLength;
-
- // Encode the contents
- switch (m_type)
- {
- default:
- {
- // No data
- break;
- }
- case TYPE_STRING:
- {
- utility::inputStreamStringProxyAdapter in(m_string);
-
- theEncoder->encode(in, os);
- break;
- }
- case TYPE_STREAM:
- {
- utility::inputStream& in = const_cast <utility::inputStream&>
- (*(m_stream ? m_stream : m_ownedStream.ptr()));
-
- in.reset(); // may not work...
-
- theEncoder->encode(in, os);
- break;
- }
-
- }
- }
-}
-
-
-void contentHandler::extract(utility::outputStream& os) const
-{
- if (m_type == TYPE_NONE)
- return;
-
- // No decoding to perform
- if (!isEncoded())
- {
- switch (m_type)
- {
- default:
- {
- // No data
- break;
- }
- case TYPE_STRING:
- {
- m_string.extract(os);
- break;
- }
- case TYPE_STREAM:
- {
- utility::inputStream& in = const_cast <utility::inputStream&>
- (*(m_stream ? m_stream : m_ownedStream.ptr()));
-
- in.reset(); // may not work...
-
- utility::bufferedStreamCopy(in, os);
- break;
- }
-
- }
- }
- // Need to decode data
- else
- {
- utility::auto_ptr <encoder> theDecoder(m_encoding.getEncoder());
-
- switch (m_type)
- {
- default:
- {
- // No data
- break;
- }
- case TYPE_STRING:
- {
- utility::inputStreamStringProxyAdapter in(m_string);
-
- theDecoder->decode(in, os);
- break;
- }
- case TYPE_STREAM:
- {
- utility::inputStream& in = const_cast <utility::inputStream&>
- (*(m_stream ? m_stream : m_ownedStream.ptr()));
-
- in.reset(); // may not work...
-
- theDecoder->decode(in, os);
- break;
- }
-
- }
- }
-}
-
-
-const string::size_type contentHandler::getLength() const
-{
- switch (m_type)
- {
- case TYPE_NONE: return (0);
- case TYPE_STRING: return (m_string.length());
- case TYPE_STREAM: return (m_length);
- }
-
- return (0);
-}
-
-
-const bool contentHandler::isEmpty() const
-{
- return (m_type == TYPE_NONE);
-}
-
-
-const bool contentHandler::isEncoded() const
-{
- return (m_encoding != NO_ENCODING);
-}
-
-
-const vmime::encoding& contentHandler::getEncoding() const
-{
- return (m_encoding);
-}
-
-
} // vmime
diff --git a/src/defaultAttachment.cpp b/src/defaultAttachment.cpp
index 263ceb8a..43842eaf 100644
--- a/src/defaultAttachment.cpp
+++ b/src/defaultAttachment.cpp
@@ -32,30 +32,40 @@ defaultAttachment::defaultAttachment()
defaultAttachment::defaultAttachment(const contentHandler& data,
const encoding& enc, const mediaType& type, const text& desc)
- : m_type(type), m_desc(desc), m_data(data), m_encoding(enc)
+ : m_type(type), m_desc(desc), m_data(data.clone()), m_encoding(enc)
{
}
defaultAttachment::defaultAttachment(const contentHandler& data,
const mediaType& type, const text& desc)
- : m_type(type), m_desc(desc), m_data(data), m_encoding(encoding::decide(data))
+ : m_type(type), m_desc(desc), m_data(data.clone()),
+ m_encoding(encoding::decide(data))
{
}
defaultAttachment::defaultAttachment(const defaultAttachment& attach)
: attachment(), m_type(attach.m_type), m_desc(attach.m_desc),
- m_data(attach.m_data), m_encoding(attach.m_encoding)
+ m_data(attach.m_data->clone()), m_encoding(attach.m_encoding)
{
}
+defaultAttachment::~defaultAttachment()
+{
+ delete (m_data);
+}
+
+
defaultAttachment& defaultAttachment::operator=(const defaultAttachment& attach)
{
+ if (m_data)
+ delete (m_data);
+
m_type = attach.m_type;
m_desc = attach.m_desc;
- m_data = attach.m_data;
+ m_data = attach.m_data->clone();
m_encoding = attach.m_encoding;
return (*this);
@@ -81,7 +91,7 @@ void defaultAttachment::generatePart(bodyPart& part) const
part.getHeader()->ContentDisposition().setValue(contentDisposition(contentDispositionTypes::ATTACHMENT));
// Set contents
- part.getBody()->getContents() = m_data;
+ part.getBody()->setContents(*m_data);
}
@@ -99,7 +109,7 @@ const text& defaultAttachment::getDescription() const
const contentHandler& defaultAttachment::getData() const
{
- return (m_data);
+ return (*m_data);
}
diff --git a/src/emptyContentHandler.cpp b/src/emptyContentHandler.cpp
new file mode 100644
index 00000000..e266c678
--- /dev/null
+++ b/src/emptyContentHandler.cpp
@@ -0,0 +1,75 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2005 Vincent Richard <[email protected]>
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+
+#include "vmime/emptyContentHandler.hpp"
+
+
+namespace vmime
+{
+
+
+emptyContentHandler::emptyContentHandler()
+{
+}
+
+
+contentHandler* emptyContentHandler::clone() const
+{
+ return new emptyContentHandler();
+}
+
+
+void emptyContentHandler::generate(utility::outputStream& /* os */, const vmime::encoding& /* enc */,
+ const string::size_type /* maxLineLength */) const
+{
+ // Nothing to do.
+}
+
+
+void emptyContentHandler::extract(utility::outputStream& /* os */) const
+{
+ // Nothing to do.
+}
+
+
+const string::size_type emptyContentHandler::getLength() const
+{
+ return (0);
+}
+
+
+const bool emptyContentHandler::isEmpty() const
+{
+ return (true);
+}
+
+
+const bool emptyContentHandler::isEncoded() const
+{
+ return (false);
+}
+
+
+const vmime::encoding& emptyContentHandler::getEncoding() const
+{
+ return (NO_ENCODING);
+}
+
+
+} // vmime
diff --git a/src/fileAttachment.cpp b/src/fileAttachment.cpp
index 9eff4af9..c156eb98 100644
--- a/src/fileAttachment.cpp
+++ b/src/fileAttachment.cpp
@@ -23,6 +23,8 @@
#include "vmime/fileAttachment.hpp"
#include "vmime/exception.hpp"
+#include "vmime/streamContentHandler.hpp"
+
namespace vmime
{
@@ -35,7 +37,7 @@ fileAttachment::fileAttachment(const string& filename, const mediaType& type, co
setData(filename);
- m_encoding = encoding::decide(m_data);
+ m_encoding = encoding::decide(*m_data);
}
@@ -62,7 +64,7 @@ void fileAttachment::setData(const string& filename)
throw exceptions::open_file_error();
}
- m_data.setData(new utility::inputStreamPointerAdapter(file, true), 0, true);
+ m_data = new streamContentHandler(new utility::inputStreamPointerAdapter(file, true), 0, true);
}
diff --git a/src/htmlTextPart.cpp b/src/htmlTextPart.cpp
index c8631142..0d2fdf17 100644
--- a/src/htmlTextPart.cpp
+++ b/src/htmlTextPart.cpp
@@ -20,14 +20,27 @@
#include "vmime/htmlTextPart.hpp"
#include "vmime/exception.hpp"
+#include "vmime/emptyContentHandler.hpp"
+#include "vmime/stringContentHandler.hpp"
+
namespace vmime
{
+htmlTextPart::htmlTextPart()
+ : m_plainText(new emptyContentHandler),
+ m_text(new emptyContentHandler)
+{
+}
+
+
htmlTextPart::~htmlTextPart()
{
free_container(m_objects);
+
+ delete (m_plainText);
+ delete (m_text);
}
@@ -39,14 +52,14 @@ const mediaType htmlTextPart::getType() const
const int htmlTextPart::getPartCount() const
{
- return (m_plainText.isEmpty() ? 1 : 2);
+ return (m_plainText->isEmpty() ? 1 : 2);
}
void htmlTextPart::generateIn(bodyPart& /* message */, bodyPart& parent) const
{
// Plain text
- if (!m_plainText.isEmpty())
+ if (!m_plainText->isEmpty())
{
// -- Create a new part
bodyPart* part = new bodyPart();
@@ -58,7 +71,7 @@ void htmlTextPart::generateIn(bodyPart& /* message */, bodyPart& parent) const
part->getHeader()->ContentTransferEncoding().setValue(encoding(encodingTypes::QUOTED_PRINTABLE));
// -- Set contents
- part->getBody()->setContents(m_plainText);
+ part->getBody()->setContents(*m_plainText);
}
// HTML text
@@ -71,7 +84,7 @@ void htmlTextPart::generateIn(bodyPart& /* message */, bodyPart& parent) const
htmlPart->getHeader()->ContentTransferEncoding().setValue(encoding(encodingTypes::QUOTED_PRINTABLE));
// -- Set contents
- htmlPart->getBody()->setContents(m_text);
+ htmlPart->getBody()->setContents(*m_text);
// Handle the case we have embedded objects
if (!m_objects.empty())
@@ -185,7 +198,8 @@ void htmlTextPart::parse(const bodyPart& message, const bodyPart& parent, const
const string data = oss.str();
- m_text = textPart.getBody()->getContents();
+ delete (m_text);
+ m_text = textPart.getBody()->getContents().clone();
try
{
@@ -234,7 +248,11 @@ void htmlTextPart::parse(const bodyPart& message, const bodyPart& parent, const
}
// Extract plain text, if any.
- findPlainTextPart(message, parent, textPart);
+ if (!findPlainTextPart(message, parent, textPart))
+ {
+ delete (m_plainText);
+ m_plainText = new emptyContentHandler();
+ }
}
@@ -279,7 +297,8 @@ bool htmlTextPart::findPlainTextPart(const bodyPart& part, const bodyPart& paren
if (ctf.getValue().getType() == mediaTypes::TEXT &&
ctf.getValue().getSubType() == mediaTypes::TEXT_PLAIN)
{
- m_plainText = p.getBody()->getContents();
+ delete (m_plainText);
+ m_plainText = p.getBody()->getContents().clone();
found = true;
}
}
@@ -326,25 +345,27 @@ void htmlTextPart::setCharset(const charset& ch)
const contentHandler& htmlTextPart::getPlainText() const
{
- return (m_plainText);
+ return (*m_plainText);
}
void htmlTextPart::setPlainText(const contentHandler& plainText)
{
- m_plainText = plainText;
+ delete (m_plainText);
+ m_plainText = plainText.clone();
}
const contentHandler& htmlTextPart::getText() const
{
- return (m_text);
+ return (*m_text);
}
void htmlTextPart::setText(const contentHandler& text)
{
- m_text = text;
+ delete (m_text);
+ m_text = text.clone();
}
@@ -406,7 +427,8 @@ const string htmlTextPart::addObject(const contentHandler& data, const mediaType
const string htmlTextPart::addObject(const string& data, const mediaType& type)
{
- return (addObject(contentHandler(data), encoding::decide(data), type));
+ stringContentHandler cts(data);
+ return (addObject(cts, encoding::decide(cts), type));
}
@@ -418,14 +440,14 @@ const string htmlTextPart::addObject(const string& data, const mediaType& type)
htmlTextPart::embeddedObject::embeddedObject
(const contentHandler& data, const encoding& enc,
const string& id, const mediaType& type)
- : m_data(data), m_encoding(enc), m_id(id), m_type(type)
+ : m_data(data.clone()), m_encoding(enc), m_id(id), m_type(type)
{
}
const contentHandler& htmlTextPart::embeddedObject::getData() const
{
- return (m_data);
+ return (*m_data);
}
diff --git a/src/plainTextPart.cpp b/src/plainTextPart.cpp
index a1902bb6..cfaf35a4 100644
--- a/src/plainTextPart.cpp
+++ b/src/plainTextPart.cpp
@@ -21,11 +21,25 @@
#include "vmime/header.hpp"
#include "vmime/exception.hpp"
+#include "vmime/emptyContentHandler.hpp"
+
namespace vmime
{
+plainTextPart::plainTextPart()
+ : m_text(new emptyContentHandler)
+{
+}
+
+
+plainTextPart::~plainTextPart()
+{
+ delete (m_text);
+}
+
+
const mediaType plainTextPart::getType() const
{
return (mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN));
@@ -50,14 +64,15 @@ void plainTextPart::generateIn(bodyPart& /* message */, bodyPart& parent) const
part->getHeader()->ContentTransferEncoding().setValue(encoding(encodingTypes::QUOTED_PRINTABLE));
// Set contents
- part->getBody()->setContents(m_text);
+ part->getBody()->setContents(*m_text);
}
void plainTextPart::parse(const bodyPart& /* message */,
const bodyPart& /* parent */, const bodyPart& textPart)
{
- m_text = textPart.getBody()->getContents();
+ delete (m_text);
+ m_text = textPart.getBody()->getContents().clone();
try
{
@@ -91,13 +106,14 @@ void plainTextPart::setCharset(const charset& ch)
const contentHandler& plainTextPart::getText() const
{
- return (m_text);
+ return (*m_text);
}
void plainTextPart::setText(const contentHandler& text)
{
- m_text = text;
+ delete (m_text);
+ m_text = text.clone();
}
diff --git a/src/streamContentHandler.cpp b/src/streamContentHandler.cpp
new file mode 100644
index 00000000..e0ff56bc
--- /dev/null
+++ b/src/streamContentHandler.cpp
@@ -0,0 +1,206 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2005 Vincent Richard <[email protected]>
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+
+#include "vmime/streamContentHandler.hpp"
+
+
+namespace vmime
+{
+
+
+streamContentHandler::streamContentHandler()
+ : m_encoding(NO_ENCODING), m_ownedStream(NULL), m_stream(NULL)
+{
+}
+
+
+streamContentHandler::streamContentHandler(utility::inputStream* is,
+ const utility::stream::size_type length, const bool own, const vmime::encoding& enc)
+{
+ setData(is, length, own, enc);
+}
+
+
+streamContentHandler::~streamContentHandler()
+{
+}
+
+
+streamContentHandler::streamContentHandler(const streamContentHandler& cts)
+ : contentHandler(), m_encoding(cts.m_encoding),
+ m_ownedStream(const_cast <utility::smart_ptr <utility::inputStream>&>(cts.m_ownedStream)),
+ m_stream(cts.m_stream), m_length(cts.m_length)
+{
+}
+
+
+contentHandler* streamContentHandler::clone() const
+{
+ return new streamContentHandler(*this);
+}
+
+
+streamContentHandler& streamContentHandler::operator=(const streamContentHandler& cts)
+{
+ m_encoding = cts.m_encoding;
+
+ m_ownedStream = const_cast <utility::smart_ptr <utility::inputStream>&>(cts.m_ownedStream);
+ m_stream = cts.m_stream;
+ m_length = cts.m_length;
+
+ return (*this);
+}
+
+
+void streamContentHandler::setData(utility::inputStream* is,
+ const utility::stream::size_type length, const bool own, const vmime::encoding& enc)
+{
+ m_encoding = enc;
+ m_length = length;
+
+ if (own)
+ {
+ m_ownedStream = is;
+ m_stream = NULL;
+ }
+ else
+ {
+ m_ownedStream = NULL;
+ m_stream = is;
+ }
+}
+
+
+void streamContentHandler::generate(utility::outputStream& os, const vmime::encoding& enc,
+ const string::size_type maxLineLength) const
+{
+ if (m_stream == NULL && m_ownedStream.ptr() == NULL)
+ return;
+
+ // Managed data is already encoded
+ if (isEncoded())
+ {
+ // The data is already encoded but the encoding specified for
+ // the generation is different from the current one. We need
+ // to re-encode data: decode from input buffer to temporary
+ // buffer, and then re-encode to output stream...
+ if (m_encoding != enc)
+ {
+ utility::auto_ptr <encoder> theDecoder(m_encoding.getEncoder());
+ utility::auto_ptr <encoder> theEncoder(enc.getEncoder());
+
+ theEncoder->getProperties()["maxlinelength"] = maxLineLength;
+
+ utility::inputStream& in = const_cast <utility::inputStream&>
+ (*(m_stream ? m_stream : m_ownedStream.ptr()));
+
+ in.reset(); // may not work...
+
+ std::ostringstream oss;
+ utility::outputStreamAdapter tempOut(oss);
+
+ theDecoder->decode(in, tempOut);
+
+ string str = oss.str();
+ utility::inputStreamStringAdapter tempIn(str);
+
+ theEncoder->encode(tempIn, os);
+ }
+ // No encoding to perform
+ else
+ {
+ utility::inputStream& in = const_cast <utility::inputStream&>
+ (*(m_stream ? m_stream : m_ownedStream.ptr()));
+
+ in.reset(); // may not work...
+
+ utility::bufferedStreamCopy(in, os);
+ }
+ }
+ // Need to encode data before
+ else
+ {
+ utility::auto_ptr <encoder> theEncoder(enc.getEncoder());
+ theEncoder->getProperties()["maxlinelength"] = maxLineLength;
+
+ utility::inputStream& in = const_cast <utility::inputStream&>
+ (*(m_stream ? m_stream : m_ownedStream.ptr()));
+
+ in.reset(); // may not work...
+
+ theEncoder->encode(in, os);
+ }
+}
+
+
+void streamContentHandler::extract(utility::outputStream& os) const
+{
+ if (m_stream == NULL && m_ownedStream.ptr() == NULL)
+ return;
+
+ // No decoding to perform
+ if (!isEncoded())
+ {
+ utility::inputStream& in = const_cast <utility::inputStream&>
+ (*(m_stream ? m_stream : m_ownedStream.ptr()));
+
+ in.reset(); // may not work...
+
+ utility::bufferedStreamCopy(in, os);
+ }
+ // Need to decode data
+ else
+ {
+ utility::auto_ptr <encoder> theDecoder(m_encoding.getEncoder());
+
+ utility::inputStream& in = const_cast <utility::inputStream&>
+ (*(m_stream ? m_stream : m_ownedStream.ptr()));
+
+ in.reset(); // may not work...
+
+ theDecoder->decode(in, os);
+ }
+}
+
+
+const string::size_type streamContentHandler::getLength() const
+{
+ return (m_length);
+}
+
+
+const bool streamContentHandler::isEmpty() const
+{
+ return (m_length == 0 || (m_stream == NULL && m_ownedStream.ptr() == NULL));
+}
+
+
+const bool streamContentHandler::isEncoded() const
+{
+ return (m_encoding != NO_ENCODING);
+}
+
+
+const vmime::encoding& streamContentHandler::getEncoding() const
+{
+ return (m_encoding);
+}
+
+
+} // vmime
diff --git a/src/stringContentHandler.cpp b/src/stringContentHandler.cpp
new file mode 100644
index 00000000..4c67756d
--- /dev/null
+++ b/src/stringContentHandler.cpp
@@ -0,0 +1,192 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2005 Vincent Richard <[email protected]>
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+
+#include "vmime/stringContentHandler.hpp"
+
+
+namespace vmime
+{
+
+
+stringContentHandler::stringContentHandler(const string& buffer, const vmime::encoding& enc)
+ : m_encoding(enc), m_string(buffer)
+{
+}
+
+
+stringContentHandler::stringContentHandler(const stringContentHandler& cts)
+ : contentHandler(), m_encoding(cts.m_encoding), m_string(cts.m_string)
+{
+}
+
+
+stringContentHandler::stringContentHandler(const utility::stringProxy& str, const vmime::encoding& enc)
+ : m_encoding(enc), m_string(str)
+{
+}
+
+
+stringContentHandler::stringContentHandler(const string& buffer, const string::size_type start,
+ const string::size_type end, const vmime::encoding& enc)
+ : m_encoding(enc), m_string(buffer, start, end)
+{
+}
+
+
+stringContentHandler::~stringContentHandler()
+{
+}
+
+
+contentHandler* stringContentHandler::clone() const
+{
+ return new stringContentHandler(*this);
+}
+
+
+stringContentHandler& stringContentHandler::operator=(const stringContentHandler& cts)
+{
+ m_encoding = cts.m_encoding;
+ m_string = cts.m_string;
+
+ return (*this);
+}
+
+
+void stringContentHandler::setData(const utility::stringProxy& str, const vmime::encoding& enc)
+{
+ m_encoding = enc;
+ m_string = str;
+}
+
+
+void stringContentHandler::setData(const string& buffer, const vmime::encoding& enc)
+{
+ m_encoding = enc;
+ m_string.set(buffer);
+}
+
+
+void stringContentHandler::setData(const string& buffer, const string::size_type start,
+ const string::size_type end, const vmime::encoding& enc)
+{
+ m_encoding = enc;
+ m_string.set(buffer, start, end);
+}
+
+
+stringContentHandler& stringContentHandler::operator=(const string& buffer)
+{
+ setData(buffer, NO_ENCODING);
+ return (*this);
+}
+
+
+void stringContentHandler::generate(utility::outputStream& os,
+ const vmime::encoding& enc, const string::size_type maxLineLength) const
+{
+ // Managed data is already encoded
+ if (isEncoded())
+ {
+ // The data is already encoded but the encoding specified for
+ // the generation is different from the current one. We need
+ // to re-encode data: decode from input buffer to temporary
+ // buffer, and then re-encode to output stream...
+ if (m_encoding != enc)
+ {
+ utility::auto_ptr <encoder> theDecoder(m_encoding.getEncoder());
+ utility::auto_ptr <encoder> theEncoder(enc.getEncoder());
+
+ theEncoder->getProperties()["maxlinelength"] = maxLineLength;
+
+ utility::inputStreamStringProxyAdapter in(m_string);
+
+ std::ostringstream oss;
+ utility::outputStreamAdapter tempOut(oss);
+
+ theDecoder->decode(in, tempOut);
+
+ string str = oss.str();
+ utility::inputStreamStringAdapter tempIn(str);
+
+ theEncoder->encode(tempIn, os);
+ }
+ // No encoding to perform
+ else
+ {
+ m_string.extract(os);
+ }
+ }
+ // Need to encode data before
+ else
+ {
+ utility::auto_ptr <encoder> theEncoder(enc.getEncoder());
+ theEncoder->getProperties()["maxlinelength"] = maxLineLength;
+
+ utility::inputStreamStringProxyAdapter in(m_string);
+
+ theEncoder->encode(in, os);
+ }
+}
+
+
+void stringContentHandler::extract(utility::outputStream& os) const
+{
+ // No decoding to perform
+ if (!isEncoded())
+ {
+ m_string.extract(os);
+ }
+ // Need to decode data
+ else
+ {
+ utility::auto_ptr <encoder> theDecoder(m_encoding.getEncoder());
+
+ utility::inputStreamStringProxyAdapter in(m_string);
+
+ theDecoder->decode(in, os);
+ }
+}
+
+
+const string::size_type stringContentHandler::getLength() const
+{
+ return (m_string.length());
+}
+
+
+const bool stringContentHandler::isEmpty() const
+{
+ return (m_string.length() == 0);
+}
+
+
+const bool stringContentHandler::isEncoded() const
+{
+ return (m_encoding != NO_ENCODING);
+}
+
+
+const vmime::encoding& stringContentHandler::getEncoding() const
+{
+ return (m_encoding);
+}
+
+
+} // vmime