Splitted 'contentHandler' into three classes: 'emptyContentHandler', 'stringContentHandler' and 'streamContentHandler'.

This commit is contained in:
Vincent Richard 2005-01-28 17:50:53 +00:00
parent fb8f12c6cf
commit 4ae97ddb09
24 changed files with 873 additions and 460 deletions

View File

@ -2,6 +2,13 @@
VERSION 0.6.3cvs
================
2005-01-28 Vincent Richard <vincent@vincent-richard.net>
* Splitted 'contentHandler' into three classes: 'emptyContentHandler',
'stringContentHandler' and 'streamContentHandler'.
* Fixed bugs with signed/unsigned char in 'parserHelpers'.
2005-01-15 Vincent Richard <vincent@vincent-richard.net>
* Fixed missing 'vmime/config.hpp' include when installing VMime

View File

@ -94,6 +94,7 @@ libvmime_sources = [
'contentTypeField.cpp', 'contentTypeField.hpp',
'dateTime.cpp', 'dateTime.hpp',
'defaultAttachment.cpp', 'defaultAttachment.hpp',
'emptyContentHandler.cpp', 'emptyContentHandler.hpp',
'encoder.cpp', 'encoder.hpp',
'encoder7bit.cpp', 'encoder7bit.hpp',
'encoder8bit.cpp', 'encoder8bit.hpp',
@ -132,6 +133,8 @@ libvmime_sources = [
'relay.cpp', 'relay.hpp',
'standardFields.hpp',
'standardParams.hpp',
'stringContentHandler.cpp', 'stringContentHandler.hpp',
'streamContentHandler.cpp', 'streamContentHandler.hpp',
'text.cpp', 'text.hpp',
'textPartFactory.cpp', 'textPartFactory.hpp',
'textPart.hpp',

View File

@ -60,7 +60,7 @@ int main()
mb.setSubject(vmime::text("My first message generated with vmime::messageBuilder"));
// Message body
mb.getTextPart()->setText(vmime::contentHandler(
mb.getTextPart()->setText(vmime::stringContentHandler(
"I'm writing this short text to test message construction " \
"using the vmime::messageBuilder component."));

View File

@ -60,7 +60,7 @@ int main()
mb.setSubject(vmime::text("My first message generated with vmime::messageBuilder"));
// Message body
mb.getTextPart()->setText(vmime::contentHandler(
mb.getTextPart()->setText(vmime::stringContentHandler(
"I'm writing this short text to test message construction " \
"with attachment, using the vmime::messageBuilder component."));

View File

@ -73,8 +73,8 @@ int main()
vmime::mediaType(vmime::mediaTypes::IMAGE, vmime::mediaTypes::IMAGE_JPEG));
// -- message text
textPart.setText(vmime::contentHandler(vmime::string("This is the <b>HTML text</b>.<br/><img src=\"") + cid + vmime::string("\"/>")));
textPart.setPlainText(vmime::contentHandler(vmime::string("This is the plain text (without HTML formatting).")));
textPart.setText(vmime::stringContentHandler(vmime::string("This is the <b>HTML text</b>.<br/><img src=\"") + cid + vmime::string("\"/>")));
textPart.setPlainText(vmime::stringContentHandler("This is the plain text (without HTML formatting)."));
// Construction
vmime::message* msg = mb.construct();

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -0,0 +1,75 @@
//
// VMime library (http://vmime.sourceforge.net)
// Copyright (C) 2002-2005 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 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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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();
}

View File

@ -0,0 +1,206 @@
//
// VMime library (http://vmime.sourceforge.net)
// Copyright (C) 2002-2005 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 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

View File

@ -0,0 +1,192 @@
//
// VMime library (http://vmime.sourceforge.net)
// Copyright (C) 2002-2005 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 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

View File

@ -68,7 +68,7 @@ namespace
{
vmime::bodyPart p1;
p1.getHeader()->getField("Foo")->setValue(vmime::string("bar"));
p1.getBody()->getContents() = "Baz";
p1.getBody()->setContents(vmime::stringContentHandler("Baz"));
assert_eq("1", "Foo: bar\r\n\r\nBaz", p1.generate());
}

View File

@ -178,12 +178,6 @@ public:
*/
const contentHandler& getContents() const;
/** Return a modifiable reference to body contents.
*
* @return body contents
*/
contentHandler& getContents();
/** Set the body contents.
*
* @param contents new body contents
@ -238,7 +232,7 @@ private:
string m_prologText;
string m_epilogText;
contentHandler m_contents;
contentHandler* m_contents;
bodyPart* m_part;
header* m_header;
@ -249,6 +243,8 @@ private:
void initNewPart(bodyPart* part);
void setContentsImpl(const contentHandler& cts);
public:
using component::parse;

View File

@ -35,87 +35,62 @@ namespace vmime
class contentHandler
{
private:
static const vmime::encoding NO_ENCODING;
public:
contentHandler();
contentHandler(const string& buffer, const vmime::encoding& enc = NO_ENCODING); // for compatibility
~contentHandler();
/** Used to specify that enclosed data is not encoded. */
static const vmime::encoding NO_ENCODING;
// Copy
contentHandler(const contentHandler& cts);
contentHandler& operator=(const contentHandler& cts);
// Set the data contained in the body.
//
// The two first functions take advantage of the COW (copy-on-write) system that
// might be implemented into std::string. This is done using "stringProxy" object.
//
// Set "enc" parameter to anything other than NO_ENCODING if the data managed by
// this content handler is already encoded with the specified encoding (so, no
// encoding/decoding will be performed on generate()/extract()). Note that the
// data may be re-encoded (that is, decoded and encoded) if the encoding passed
// to generate() is different from this one...
//
// The 'length' parameter is optional (user-defined). You can pass 0 if you want,
// VMime does not make use of it.
void setData(const utility::stringProxy& str, const vmime::encoding& enc = NO_ENCODING);
void setData(const string& buffer, const vmime::encoding& enc = NO_ENCODING);
void setData(const string& buffer, const string::size_type start, const string::size_type end, const vmime::encoding& enc = NO_ENCODING);
void setData(utility::inputStream* is, const utility::stream::size_type length, const bool own, const vmime::encoding& enc = NO_ENCODING);
virtual ~contentHandler();
// For compatibility
contentHandler& operator=(const string& buffer);
/** Return a copy of this object.
*
* @return copy of this object
*/
virtual contentHandler* clone() const = 0;
// WRITE: Output the contents into the specified stream. Data will be
// encoded before being written into the stream. This is used internally
// by the body object to generate the message, you may not need to use
// this (see function extract() if you want to get the contents).
void generate(utility::outputStream& os, const vmime::encoding& enc, const string::size_type maxLineLength = lineLengthLimits::infinite) const;
/** Output the contents into the specified stream. Data will be
* encoded before being written into the stream. This is used internally
* by the body object to generate the message, you may not need to use
* this (see contentHandler::extract() if you want to get the contents).
*
* @param os output stream
* @param enc encoding for output
* @param maxLineLength maximum line length for output
*/
virtual void generate(utility::outputStream& os, const vmime::encoding& enc, const string::size_type maxLineLength = lineLengthLimits::infinite) const = 0;
// READ: Extract the contents into the specified stream. If needed, data
// will be decoded before being written into the stream.
void extract(utility::outputStream& os) const;
/** Extract the contents into the specified stream. If needed, data
* will be decoded before being written into the stream.
*
* @param os output stream
*/
virtual void extract(utility::outputStream& os) const = 0;
// Returns the actual length of the data. WARNING: this can return 0 if no
// length was specified when setting data of this object.
const string::size_type getLength() const;
/** Returns the actual length of data. WARNING: this can return 0 if no
* length was specified when setting data of this object.
*
* @return length of data
*/
virtual const string::size_type getLength() const = 0;
// Returns 'true' if the data managed by this object is encoded.
const bool isEncoded() const;
/** Returns 'true' if data managed by this object is encoded.
*
* @return true if data is encoded, false otherwise
*/
virtual const bool isEncoded() const = 0;
// Returns the encoding used for the data (or "binary" if not encoded).
const vmime::encoding& getEncoding() const;
/** Returns the encoding used for data (or "binary" if not encoded).
*
* @return encoding used for data
*/
virtual const vmime::encoding& getEncoding() const = 0;
// Returns 'true' if there is no data set.
const bool isEmpty() const;
private:
// Source of data managed by this content handler
enum Types
{
TYPE_NONE,
TYPE_STRING,
TYPE_STREAM
};
Types m_type;
// Equals to NO_ENCODING if data is not encoded, otherwise this
// specifies the encoding that have been used to encode the data.
vmime::encoding m_encoding;
// Used if m_type == TYPE_STRING
utility::stringProxy m_string;
// Used if m_type == TYPE_STREAM
utility::smart_ptr <utility::inputStream> m_ownedStream; // 'contentHandler' objects are copiable...
utility::inputStream* m_stream;
string::size_type m_length;
/** Returns 'true' if there is no data set.
*
* @return true if no data is managed by this object, false otherwise
*/
virtual const bool isEmpty() const = 0;
};

View File

@ -45,6 +45,8 @@ public:
defaultAttachment(const contentHandler& data, const mediaType& type, const text& desc = NULL_TEXT);
defaultAttachment(const defaultAttachment& attach);
~defaultAttachment();
defaultAttachment& operator=(const defaultAttachment& attach);
const mediaType& getType() const;
@ -56,7 +58,7 @@ protected:
mediaType m_type; // Media type (eg. "application/octet-stream")
text m_desc; // Description (eg. "The image you requested")
contentHandler m_data; // Attachment data (eg. the file contents)
contentHandler* m_data; // Attachment data (eg. the file contents)
encoding m_encoding; // Encoding
private:

View File

@ -0,0 +1,56 @@
//
// VMime library (http://vmime.sourceforge.net)
// Copyright (C) 2002-2005 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 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.
//
#ifndef VMIME_EMPTYCONTENTHANDLER_HPP_INCLUDED
#define VMIME_EMPTYCONTENTHANDLER_HPP_INCLUDED
#include "vmime/contentHandler.hpp"
namespace vmime
{
class emptyContentHandler : public contentHandler
{
public:
emptyContentHandler();
contentHandler* clone() const;
void generate(utility::outputStream& os, const vmime::encoding& enc, const string::size_type maxLineLength = lineLengthLimits::infinite) const;
void extract(utility::outputStream& os) const;
const string::size_type getLength() const;
const bool isEncoded() const;
const vmime::encoding& getEncoding() const;
const bool isEmpty() const;
};
} // vmime
#endif // VMIME_EMPTYCONTENTHANDLER_HPP_INCLUDED

View File

@ -43,6 +43,8 @@ protected:
public:
htmlTextPart();
const mediaType getType() const;
const charset& getCharset() const;
@ -91,7 +93,7 @@ public:
private:
contentHandler m_data;
contentHandler* m_data;
encoding m_encoding;
string m_id;
mediaType m_type;
@ -160,8 +162,8 @@ public:
private:
contentHandler m_plainText;
contentHandler m_text;
contentHandler* m_plainText;
contentHandler* m_text;
charset m_charset;
std::vector <embeddedObject*> m_objects;

View File

@ -35,6 +35,9 @@ class plainTextPart : public textPart
{
public:
plainTextPart();
~plainTextPart();
const mediaType getType() const;
const charset& getCharset() const;
@ -45,7 +48,7 @@ public:
private:
contentHandler m_text;
contentHandler* m_text;
charset m_charset;
const int getPartCount() const;

View File

@ -0,0 +1,76 @@
//
// VMime library (http://vmime.sourceforge.net)
// Copyright (C) 2002-2005 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 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.
//
#ifndef VMIME_STREAMCONTENTHANDLER_HPP_INCLUDED
#define VMIME_STREAMCONTENTHANDLER_HPP_INCLUDED
#include "vmime/contentHandler.hpp"
namespace vmime
{
class streamContentHandler : public contentHandler
{
public:
streamContentHandler();
streamContentHandler(utility::inputStream* is, const utility::stream::size_type length, const bool own, const vmime::encoding& enc = NO_ENCODING);
~streamContentHandler();
streamContentHandler(const streamContentHandler& cts);
streamContentHandler& operator=(const streamContentHandler& cts);
contentHandler* clone() const;
void setData(utility::inputStream* is, const utility::stream::size_type length, const bool own, const vmime::encoding& enc = NO_ENCODING);
void generate(utility::outputStream& os, const vmime::encoding& enc, const string::size_type maxLineLength = lineLengthLimits::infinite) const;
void extract(utility::outputStream& os) const;
const string::size_type getLength() const;
const bool isEncoded() const;
const vmime::encoding& getEncoding() const;
const bool isEmpty() const;
private:
// Equals to NO_ENCODING if data is not encoded, otherwise this
// specifies the encoding that have been used to encode the data.
vmime::encoding m_encoding;
// Actual data
utility::smart_ptr <utility::inputStream> m_ownedStream; // 'contentHandler' objects are copiable...
utility::inputStream* m_stream;
string::size_type m_length;
};
} // vmime
#endif // VMIME_STREAMCONTENTHANDLER_HPP_INCLUDED

View File

@ -0,0 +1,92 @@
//
// VMime library (http://vmime.sourceforge.net)
// Copyright (C) 2002-2005 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 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.
//
#ifndef VMIME_STRINGCONTENTHANDLER_HPP_INCLUDED
#define VMIME_STRINGCONTENTHANDLER_HPP_INCLUDED
#include "vmime/contentHandler.hpp"
namespace vmime
{
class stringContentHandler : public contentHandler
{
public:
stringContentHandler();
stringContentHandler(const string& buffer, const vmime::encoding& enc = NO_ENCODING);
stringContentHandler(const utility::stringProxy& str, const vmime::encoding& enc = NO_ENCODING);
stringContentHandler(const string& buffer, const string::size_type start, const string::size_type end, const vmime::encoding& enc = NO_ENCODING);
~stringContentHandler();
stringContentHandler(const stringContentHandler& cts);
stringContentHandler& operator=(const stringContentHandler& cts);
contentHandler* clone() const;
// Set the data contained in the body.
//
// The two first functions take advantage of the COW (copy-on-write) system that
// might be implemented into std::string. This is done using "stringProxy" object.
//
// Set "enc" parameter to anything other than NO_ENCODING if the data managed by
// this content handler is already encoded with the specified encoding (so, no
// encoding/decoding will be performed on generate()/extract()). Note that the
// data may be re-encoded (that is, decoded and encoded) if the encoding passed
// to generate() is different from this one...
//
// The 'length' parameter is optional (user-defined). You can pass 0 if you want,
// VMime does not make use of it.
void setData(const utility::stringProxy& str, const vmime::encoding& enc = NO_ENCODING);
void setData(const string& buffer, const vmime::encoding& enc = NO_ENCODING);
void setData(const string& buffer, const string::size_type start, const string::size_type end, const vmime::encoding& enc = NO_ENCODING);
stringContentHandler& operator=(const string& buffer);
void generate(utility::outputStream& os, const vmime::encoding& enc, const string::size_type maxLineLength = lineLengthLimits::infinite) const;
void extract(utility::outputStream& os) const;
const string::size_type getLength() const;
const bool isEncoded() const;
const vmime::encoding& getEncoding() const;
const bool isEmpty() const;
private:
// Equals to NO_ENCODING if data is not encoded, otherwise this
// specifies the encoding that have been used to encode the data.
vmime::encoding m_encoding;
// The actual data
utility::stringProxy m_string;
};
} // vmime
#endif // VMIME_STRINGCONTENTHANDLER_HPP_INCLUDED

View File

@ -46,6 +46,10 @@
#include "vmime/messageId.hpp"
#include "vmime/relay.hpp"
#include "vmime/emptyContentHandler.hpp"
#include "vmime/stringContentHandler.hpp"
#include "vmime/streamContentHandler.hpp"
// Message components
#include "vmime/message.hpp"