diff options
Diffstat (limited to 'vmime')
38 files changed, 899 insertions, 239 deletions
diff --git a/vmime/address.hpp b/vmime/address.hpp index 8a00c04c..0faf876f 100644 --- a/vmime/address.hpp +++ b/vmime/address.hpp @@ -65,13 +65,17 @@ public: /** Parse an address from an input buffer. * + * @param ctx parsing context * @param buffer input buffer * @param position position in the input buffer * @param end end position in the input buffer * @param newPosition will receive the new position in the input buffer * @return a new address object, or null if no more address is available in the input buffer */ - static ref <address> parseNext(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition); + static ref <address> parseNext + (const parsingContext& ctx, const string& buffer, + const string::size_type position, const string::size_type end, + string::size_type* newPosition); }; diff --git a/vmime/addressList.hpp b/vmime/addressList.hpp index b4694724..b7bb40cb 100644 --- a/vmime/addressList.hpp +++ b/vmime/addressList.hpp @@ -167,14 +167,15 @@ protected: // Component parsing & assembling void parseImpl - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); void generateImpl - (utility::outputStream& os, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; }; diff --git a/vmime/body.hpp b/vmime/body.hpp index 4d563ebd..3ba140c8 100644 --- a/vmime/body.hpp +++ b/vmime/body.hpp @@ -303,14 +303,15 @@ protected: // Component parsing & assembling void parseImpl - (ref <utility::parserInputStreamAdapter> parser, + (const parsingContext& ctx, + ref <utility::parserInputStreamAdapter> parser, const utility::stream::size_type position, const utility::stream::size_type end, utility::stream::size_type* newPosition = NULL); void generateImpl - (utility::outputStream& os, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; }; diff --git a/vmime/bodyPart.hpp b/vmime/bodyPart.hpp index 6b96e923..5972cea3 100644 --- a/vmime/bodyPart.hpp +++ b/vmime/bodyPart.hpp @@ -114,14 +114,15 @@ protected: // Component parsing & assembling void parseImpl - (ref <utility::parserInputStreamAdapter> parser, + (const parsingContext& ctx, + ref <utility::parserInputStreamAdapter> parser, const utility::stream::size_type position, const utility::stream::size_type end, utility::stream::size_type* newPosition = NULL); void generateImpl - (utility::outputStream& os, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; }; diff --git a/vmime/charset.hpp b/vmime/charset.hpp index 24f3f79c..e2de7ebb 100644 --- a/vmime/charset.hpp +++ b/vmime/charset.hpp @@ -28,6 +28,7 @@ #include "vmime/base.hpp" #include "vmime/utility/inputStream.hpp" #include "vmime/utility/outputStream.hpp" +#include "vmime/charsetConverterOptions.hpp" #include "vmime/component.hpp" @@ -93,10 +94,13 @@ public: * @param out output buffer * @param source input charset * @param dest output charset + * @param opts conversion options * @throws exceptions::charset_conv_error if an error occured during * the conversion */ - static void convert(const string& in, string& out, const charset& source, const charset& dest); + static void convert(const string& in, string& out, + const charset& source, const charset& dest, + const charsetConverterOptions& opts = charsetConverterOptions()); /** Convert the contents of an input stream in a specified charset * to another charset and write the result to an output stream. @@ -105,10 +109,13 @@ public: * @param out output stream to write the converted data * @param source input charset * @param dest output charset + * @param opts conversion options * @throws exceptions::charset_conv_error if an error occured during * the conversion */ - static void convert(utility::inputStream& in, utility::outputStream& out, const charset& source, const charset& dest); + static void convert(utility::inputStream& in, utility::outputStream& out, + const charset& source, const charset& dest, + const charsetConverterOptions& opts = charsetConverterOptions()); ref <component> clone() const; void copyFrom(const component& other); @@ -121,14 +128,15 @@ protected: // Component parsing & assembling void parseImpl - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); void generateImpl - (utility::outputStream& os, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; }; diff --git a/vmime/charsetConverter.hpp b/vmime/charsetConverter.hpp index a76cc69d..b7292d66 100644 --- a/vmime/charsetConverter.hpp +++ b/vmime/charsetConverter.hpp @@ -29,6 +29,7 @@ #include "vmime/component.hpp" #include "vmime/charset.hpp" +#include "vmime/charsetConverterOptions.hpp" #include "vmime/utility/filteredStream.hpp" @@ -36,6 +37,25 @@ namespace vmime { +namespace utility +{ + + +/** A filtered output stream which applies a charset conversion + * to input bytes. + * + * May throw a exceptions::charset_conv_error if an error + * occured when initializing convert, or during charset conversion. + */ + +class charsetFilteredOutputStream : public filteredOutputStream +{ +}; + + +} // utility + + /** Convert between charsets. */ @@ -43,14 +63,15 @@ class charsetConverter : public object { public: - /** Construct and initialize a charset converter. + /** Construct and initialize an iconv charset converter. * * @param source input charset * @param dest output charset + * @param opts conversion options */ - charsetConverter(const charset& source, const charset& dest); - - ~charsetConverter(); + static ref <charsetConverter> create + (const charset& source, const charset& dest, + const charsetConverterOptions& opts = charsetConverterOptions()); /** Convert a string buffer from one charset to another * charset (in-memory conversion) @@ -63,7 +84,7 @@ public: * @throws exceptions::charset_conv_error if an error occured during * the conversion */ - void convert(const string& in, string& out); + virtual void convert(const string& in, string& out) = 0; /** Convert the contents of an input stream in a specified charset * to another charset and write the result to an output stream. @@ -73,78 +94,20 @@ public: * @throws exceptions::charset_conv_error if an error occured during * the conversion */ - void convert(utility::inputStream& in, utility::outputStream& out); - -private: - - void* m_desc; + virtual void convert(utility::inputStream& in, utility::outputStream& out) = 0; - charset m_source; - charset m_dest; -}; - - -namespace utility { - - -/** A filtered output stream which applies a charset conversion - * to input bytes. - * - * May throw a exceptions::charset_conv_error if an error - * occured when initializing convert, or during charset conversion. - */ - -class charsetFilteredOutputStream : public filteredOutputStream -{ -public: - - /** Construct a new filter for the specified output stream. + /** Returns a filtered output stream which applies a charset + * conversion to input bytes. Please note that it may not be + * supported by the converter. * - * @param source input charset - * @param dest output charset - * @param os stream into which write filtered data + * @param os stream into which filtered data will be written + * @return a filtered output stream, or NULL if not supported */ - charsetFilteredOutputStream - (const charset& source, const charset& dest, outputStream& os); - - ~charsetFilteredOutputStream(); - - - outputStream& getNextOutputStream(); - - void write(const value_type* const data, const size_type count); - void flush(); - -private: - - // Maximum character width in any charset - enum { MAX_CHARACTER_WIDTH = 128 }; - - - void* m_desc; - - const charset m_sourceCharset; - const charset m_destCharset; - - outputStream& m_stream; - - // Buffer in which unconverted bytes are left until they can - // be converted (when more data arrives). The length should be - // large enough to contain any character in any charset. - value_type m_unconvBuffer[MAX_CHARACTER_WIDTH]; - size_type m_unconvCount; - - // Buffer used for conversion. Avoids declaring it in write(). - // Should be at least MAX_CHARACTER_WIDTH * MAX_CHARACTER_WIDTH. - value_type m_outputBuffer[32768]; + virtual ref <utility::charsetFilteredOutputStream> getFilteredOutputStream(utility::outputStream& os) = 0; }; -} // utility - - } // vmime #endif // VMIME_CHARSETCONVERTER_HPP_INCLUDED - diff --git a/vmime/options.hpp b/vmime/charsetConverterOptions.hpp index 1413b1a3..ee75c1cb 100644 --- a/vmime/options.hpp +++ b/vmime/charsetConverterOptions.hpp @@ -21,8 +21,8 @@ // the GNU General Public License cover the whole combination. // -#ifndef VMIME_OPTIONS_HPP_INCLUDED -#define VMIME_OPTIONS_HPP_INCLUDED +#ifndef VMIME_CHARSETCONVERTEROPTIONS_HPP_INCLUDED +#define VMIME_CHARSETCONVERTEROPTIONS_HPP_INCLUDED #include "vmime/base.hpp" @@ -32,66 +32,22 @@ namespace vmime { -/** A class to set global options for VMime. +/** Options for charset conversion. */ -class options +class charsetConverterOptions : public object { -protected: - - /** Message-related options. - */ - class messageOptions - { - protected: - - friend class options; - - messageOptions() - : m_maxLineLength(lineLengthLimits::convenient) - { - } - - string::size_type m_maxLineLength; - - public: - - const string::size_type& maxLineLength() const { return (m_maxLineLength); } - string::size_type& maxLineLength() { return (m_maxLineLength); } - }; - - /** Multipart-related options. - */ - class multipartOptions - { - private: - - friend class options; - - multipartOptions(); - - string m_prologText; - string m_epilogText; - - public: - - const string& getPrologText() const; - void setPrologText(const string& prologText); - - const string& getEpilogText() const; - void setEpilogText(const string& epilogText); - }; - public: - static options* getInstance(); + charsetConverterOptions(); + - multipartOptions multipart; - messageOptions message; + /** Replace invalid sequences with this string. */ + string invalidSequence; }; } // vmime -#endif // VMIME_OPTIONS_HPP_INCLUDED +#endif // VMIME_CHARSETCONVERTEROPTIONS_HPP_INCLUDED diff --git a/vmime/charsetConverter_iconv.hpp b/vmime/charsetConverter_iconv.hpp new file mode 100644 index 00000000..77a6651c --- /dev/null +++ b/vmime/charsetConverter_iconv.hpp @@ -0,0 +1,124 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 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 3 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. +// + +#ifndef VMIME_CHARSETCONVERTER_ICONV_HPP_INCLUDED +#define VMIME_CHARSETCONVERTER_ICONV_HPP_INCLUDED + + +#include "vmime/charsetConverter.hpp" + + +namespace vmime +{ + + +/** A generic charset converter which uses iconv library. + */ + +class charsetConverter_iconv : public charsetConverter +{ +public: + + /** Construct and initialize an iconv charset converter. + * + * @param source input charset + * @param dest output charset + * @param opts conversion options + */ + charsetConverter_iconv(const charset& source, const charset& dest, + const charsetConverterOptions& opts = charsetConverterOptions()); + + ~charsetConverter_iconv(); + + void convert(const string& in, string& out); + void convert(utility::inputStream& in, utility::outputStream& out); + + ref <utility::charsetFilteredOutputStream> getFilteredOutputStream(utility::outputStream& os); + +private: + + void* m_desc; + + charset m_source; + charset m_dest; + + charsetConverterOptions m_options; +}; + + +namespace utility { + + +class charsetFilteredOutputStream_iconv : public charsetFilteredOutputStream +{ +public: + + /** Construct a new filter for the specified output stream. + * + * @param source input charset + * @param dest output charset + * @param os stream into which write filtered data + */ + charsetFilteredOutputStream_iconv + (const charset& source, const charset& dest, outputStream* os); + + ~charsetFilteredOutputStream_iconv(); + + + outputStream& getNextOutputStream(); + + void write(const value_type* const data, const size_type count); + void flush(); + +private: + + // Maximum character width in any charset + enum { MAX_CHARACTER_WIDTH = 128 }; + + + void* m_desc; + + const charset m_sourceCharset; + const charset m_destCharset; + + outputStream& m_stream; + + // Buffer in which unconverted bytes are left until they can + // be converted (when more data arrives). The length should be + // large enough to contain any character in any charset. + value_type m_unconvBuffer[MAX_CHARACTER_WIDTH]; + size_type m_unconvCount; + + // Buffer used for conversion. Avoids declaring it in write(). + // Should be at least MAX_CHARACTER_WIDTH * MAX_CHARACTER_WIDTH. + value_type m_outputBuffer[32768]; +}; + + +} // utility + + +} // vmime + + +#endif // VMIME_CHARSETCONVERTER_ICONV_HPP_INCLUDED diff --git a/vmime/charsetConverter_idna.hpp b/vmime/charsetConverter_idna.hpp new file mode 100644 index 00000000..d3b8b25f --- /dev/null +++ b/vmime/charsetConverter_idna.hpp @@ -0,0 +1,70 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 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 3 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. +// + +#ifndef VMIME_CHARSETCONVERTER_IDNA_HPP_INCLUDED +#define VMIME_CHARSETCONVERTER_IDNA_HPP_INCLUDED + + +#include "vmime/charsetConverter.hpp" + + +namespace vmime +{ + + +/** A charset converter which can convert to and from Punycode (for IDNA). + */ + +class charsetConverter_idna : public charsetConverter +{ +public: + + /** Construct and initialize an IDNA charset converter. + * + * @param source input charset + * @param dest output charset + * @param opts conversion options + */ + charsetConverter_idna(const charset& source, const charset& dest, + const charsetConverterOptions& opts = charsetConverterOptions()); + + ~charsetConverter_idna(); + + void convert(const string& in, string& out); + void convert(utility::inputStream& in, utility::outputStream& out); + + ref <utility::charsetFilteredOutputStream> getFilteredOutputStream(utility::outputStream& os); + +private: + + charset m_source; + charset m_dest; + + charsetConverterOptions m_options; +}; + + +} // vmime + + +#endif // VMIME_CHARSETCONVERTER_IDNA_HPP_INCLUDED diff --git a/vmime/component.hpp b/vmime/component.hpp index f12a2b6a..3dca5f66 100644 --- a/vmime/component.hpp +++ b/vmime/component.hpp @@ -30,6 +30,8 @@ #include "vmime/utility/seekableInputStream.hpp" #include "vmime/utility/parserInputStreamAdapter.hpp" #include "vmime/utility/outputStream.hpp" +#include "vmime/generationContext.hpp" +#include "vmime/parsingContext.hpp" namespace vmime @@ -47,19 +49,31 @@ public: component(); virtual ~component(); - /** Parse RFC-822/MIME data for this component. + /** Parse RFC-822/MIME data for this component, using the default + * parsing context. * * @param buffer input buffer */ void parse(const string& buffer); + /** Parse RFC-822/MIME data for this component. + * + * @param ctx parsing context + * @param buffer input buffer + */ + void parse(const parsingContext& ctx, const string& buffer); + /** Parse RFC-822/MIME data for this component. If stream is not seekable, * or if length is not specified, entire contents of the stream will * be loaded into memory before parsing. + * + * @param inputStream stream from which to read data + * @param length data length, in bytes (0 = unknown/not specified) */ void parse(ref <utility::inputStream> inputStream, const utility::stream::size_type length); - /** Parse RFC-822/MIME data for this component. + /** Parse RFC-822/MIME data for this component, using the default + * parsing context. * * @param buffer input buffer * @param position current position in the input buffer @@ -72,9 +86,25 @@ public: const string::size_type end, string::size_type* newPosition = NULL); + /** Parse RFC-822/MIME data for this component. + * + * @param ctx parsing context + * @param buffer input buffer + * @param position current position in the input buffer + * @param end end position in the input buffer + * @param newPosition will receive the new position in the input buffer + */ + void parse + (const parsingContext& ctx, + const string& buffer, + const string::size_type position, + const string::size_type end, + string::size_type* newPosition = NULL); + /** Parse RFC-822/MIME data for this component. If stream is not seekable, * or if end position is not specified, entire contents of the stream will - * be loaded into memory before parsing. + * be loaded into memory before parsing. The default parsing context + * will be used. * * @param inputStream stream from which to read data * @param position current position in the input stream @@ -87,6 +117,23 @@ public: const utility::stream::size_type end, utility::stream::size_type* newPosition = NULL); + /** Parse RFC-822/MIME data for this component. If stream is not seekable, + * or if end position is not specified, entire contents of the stream will + * be loaded into memory before parsing. + * + * @param ctx parsing context + * @param inputStream stream from which to read data + * @param position current position in the input stream + * @param end end position in the input stream + * @param newPosition will receive the new position in the input stream + */ + void parse + (const parsingContext& ctx, + ref <utility::inputStream> inputStream, + const utility::stream::size_type position, + const utility::stream::size_type end, + utility::stream::size_type* newPosition = NULL); + /** Generate RFC-2822/MIME data for this component. * * \deprecated Use the new generate() method, which takes an outputStream parameter. @@ -99,7 +146,7 @@ public: (const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0) const; - /** Generate RFC-2822/MIME data for this component. + /** Generate RFC-2822/MIME data for this component, using the default generation context. * * @param outputStream output stream * @param maxLineLength maximum line length for output @@ -108,20 +155,20 @@ public: */ virtual void generate (utility::outputStream& outputStream, - const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; - /** Generate RFC-2822/MIME data for this component. + /** Generate RFC-2822/MIME data for this component, using the default generation context. * + * @param ctx generation context * @param outputStream output stream * @param maxLineLength maximum line length for output * @param curLinePos length of the current line in the output buffer * @param newLinePos will receive the new line position (length of the last line written) */ virtual void generate - (ref <utility::outputStream> outputStream, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& outputStream, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; @@ -168,20 +215,22 @@ protected: // AT LEAST ONE of these parseImpl() functions MUST be implemented in derived class virtual void parseImpl - (ref <utility::parserInputStreamAdapter> parser, + (const parsingContext& ctx, + ref <utility::parserInputStreamAdapter> parser, const utility::stream::size_type position, const utility::stream::size_type end, utility::stream::size_type* newPosition = NULL); virtual void parseImpl - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); virtual void generateImpl - (utility::outputStream& os, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const = 0; diff --git a/vmime/constants.hpp b/vmime/constants.hpp index b5a1a0d4..59c89f0e 100644 --- a/vmime/constants.hpp +++ b/vmime/constants.hpp @@ -164,6 +164,8 @@ namespace vmime extern const string::value_type* const WINDOWS_1256; extern const string::value_type* const WINDOWS_1257; extern const string::value_type* const WINDOWS_1258; + + extern const string::value_type* const IDNA; } /** Constants for standard field names. */ diff --git a/vmime/contentDisposition.hpp b/vmime/contentDisposition.hpp index e876edef..69c0f313 100644 --- a/vmime/contentDisposition.hpp +++ b/vmime/contentDisposition.hpp @@ -79,14 +79,15 @@ protected: // Component parsing & assembling void parseImpl - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); void generateImpl - (utility::outputStream& os, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; }; diff --git a/vmime/context.hpp b/vmime/context.hpp new file mode 100644 index 00000000..76cc0ee4 --- /dev/null +++ b/vmime/context.hpp @@ -0,0 +1,122 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 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 3 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. +// + +#ifndef VMIME_CONTEXT_HPP_INCLUDED +#define VMIME_CONTEXT_HPP_INCLUDED + + +#include "vmime/base.hpp" +#include "vmime/charsetConverterOptions.hpp" + + +namespace vmime +{ + + +/** Holds configuration parameters used either for parsing or generating messages. + */ + +class context : public object +{ +public: + + virtual ~context(); + + /** Returns whether support for Internationalized Email Headers (RFC-6532) + * is enabled. + * + * @return true if RFC-6532 support is enabled, false otherwise + */ + bool getInternationalizedEmailSupport() const; + + /** Enables or disables support for Internationalized Email Headers (RFC-6532). + * This is disabled by default, and should be used only with servers + * which support it (eg. SMTP servers with SMTPUTF8 extension). + * + * @param support true if RFC-6532 support is enabled, false otherwise + */ + void setInternationalizedEmailSupport(const bool support); + + /** Returns options used currently for charset conversions by the parser and/or + * the generator. See charsetConverterOptions class for more information. + * + * @return current charset conversion options + */ + const charsetConverterOptions& getCharsetConversionOptions() const; + + /** Sets the options used currently for charset conversions by the parser and/or + * the generator. See charsetConverterOptions class for more information. + * + * @param opts new charset conversion options + */ + void setCharsetConversionOptions(const charsetConverterOptions& opts); + + /** Switches between contexts temporarily. + */ + template <typename CTX_CLASS> + class switcher + { + public: + + /** Switches to the specified context. + * Default context will temporarily use the data of the specified + * new context during the lifetime of this object. + * + * @param newCtx new context + */ + switcher(CTX_CLASS& newCtx) + : m_oldCtxData(CTX_CLASS::getDefaultContext()), m_newCtx(&newCtx) + { + CTX_CLASS::getDefaultContext().copyFrom(newCtx); + } + + /** Restores back saved context. + */ + ~switcher() + { + CTX_CLASS::getDefaultContext().copyFrom(m_oldCtxData); + } + + private: + + CTX_CLASS m_oldCtxData; + CTX_CLASS* m_newCtx; + }; + +protected: + + context(); + context(const context& ctx); + + virtual context& operator=(const context& ctx); + virtual void copyFrom(const context& ctx); + + bool m_internationalizedEmail; + charsetConverterOptions m_charsetConvOptions; +}; + + +} // vmime + + +#endif // VMIME_CONTEXT_HPP_INCLUDED diff --git a/vmime/dateTime.hpp b/vmime/dateTime.hpp index 0c1d3971..b7f5d273 100644 --- a/vmime/dateTime.hpp +++ b/vmime/dateTime.hpp @@ -243,14 +243,15 @@ protected: // Component parsing & assembling void parseImpl - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); void generateImpl - (utility::outputStream& os, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; }; diff --git a/vmime/disposition.hpp b/vmime/disposition.hpp index 66dd8933..1c14f532 100644 --- a/vmime/disposition.hpp +++ b/vmime/disposition.hpp @@ -138,14 +138,15 @@ protected: // Component parsing & assembling void parseImpl - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); void generateImpl - (utility::outputStream& os, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; }; diff --git a/vmime/emailAddress.hpp b/vmime/emailAddress.hpp new file mode 100644 index 00000000..e9512d98 --- /dev/null +++ b/vmime/emailAddress.hpp @@ -0,0 +1,121 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 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 3 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. +// + +#ifndef VMIME_EMAILADDRESS_HPP_INCLUDED +#define VMIME_EMAILADDRESS_HPP_INCLUDED + + +#include "vmime/component.hpp" +#include "vmime/text.hpp" + + +namespace vmime +{ + + +/** An email address: local name and domain name (basic type). + */ + +class emailAddress : public component +{ +public: + + emailAddress(); + emailAddress(const emailAddress& eml); + emailAddress(const string& email); + emailAddress(const char* email); + emailAddress(const string& localName, const string& domainName); + emailAddress(const word& localName, const word& domainName); + + /** Return the local name of the address. + * + * @return local name of the address + */ + const word& getLocalName() const; + + /** Set the local name of the address. + * + * @param name local name of the address + */ + void setLocalName(const word& localName); + + /** Return the domain name of the address. + * + * @return domain name of the address + */ + const word& getDomainName() const; + + /** Set the domain name of the address. + * + * @param domain domain name of the address + */ + void setDomainName(const word& domainName); + + /** Returns whether this email address is empty. + * Address is considered as empty if the local part is not specified. + * + * @return true if the address is empty, false otherwise + */ + bool isEmpty() const; + + // Comparison + bool operator==(const class emailAddress& eml) const; + bool operator!=(const class emailAddress& eml) const; + + // Assignment + void copyFrom(const component& other); + ref <component> clone() const; + emailAddress& operator=(const emailAddress& other); + + const std::vector <ref <component> > getChildComponents(); + +protected: + + word m_localName; + word m_domainName; + +public: + + using component::parse; + using component::generate; + + // Component parsing & assembling + void parseImpl + (const parsingContext& ctx, + const string& buffer, + const string::size_type position, + const string::size_type end, + string::size_type* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const string::size_type curLinePos = 0, + string::size_type* newLinePos = NULL) const; +}; + + +} // vmime + + +#endif // VMIME_EMAILADDRESS_HPP_INCLUDED diff --git a/vmime/encoding.hpp b/vmime/encoding.hpp index e1d91bb5..4266856f 100644 --- a/vmime/encoding.hpp +++ b/vmime/encoding.hpp @@ -152,14 +152,15 @@ protected: // Component parsing & assembling void parseImpl - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); void generateImpl - (utility::outputStream& os, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; }; diff --git a/vmime/generationContext.hpp b/vmime/generationContext.hpp new file mode 100644 index 00000000..cf7e7499 --- /dev/null +++ b/vmime/generationContext.hpp @@ -0,0 +1,106 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 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 3 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. +// + +#ifndef VMIME_GENERATIONCONTEXT_HPP_INCLUDED +#define VMIME_GENERATIONCONTEXT_HPP_INCLUDED + + +#include "vmime/context.hpp" + + +namespace vmime +{ + + +/** Holds configuration parameters used for generating messages. + */ + +class generationContext : public context +{ +public: + + generationContext(); + generationContext(const generationContext& ctx); + + /** Returns the current maximum line length used when generating messages. + * + * @return current maximum line length, in bytes + */ + string::size_type getMaxLineLength() const; + + /** Sets the maximum line length used when generating messages. + * You may use the constants lineLengthLimits::convenient, + * lineLengthLimits::max and lineLengthLimits::infinite. + * + * @param maxLineLength new maximum line length, in bytes + */ + void setMaxLineLength(const string::size_type maxLineLength); + + /** Returns the current prolog text used when generating MIME body parts. + * + * @return current MIME prolog text + */ + const string getPrologText() const; + + /** Sets the prolog text used when generating MIME body parts. This text + * appears before the part, and should be displayed by MUAs which do not + * support MIME. This should be 7-bit ASCII text only. + * + * @param prologText MIME prolog text + */ + void setPrologText(const string& prologText); + + /** Returns the current epilog text used when generating MIME body parts. + * + * @return current MIME epilog text + */ + const string getEpilogText() const; + + /** Sets the epilog text used when generating MIME body parts. This test + * appears after the part, and should be displayed by MUAs which do not + * support MIME. This should be 7-bit ASCII text only. + */ + void setEpilogText(const string& epilogText); + + /** Returns the default context used for generating messages. + * + * @return a reference to the default generation context + */ + static generationContext& getDefaultContext(); + + generationContext& operator=(const generationContext& ctx); + void copyFrom(const generationContext& ctx); + +protected: + + string::size_type m_maxLineLength; + + string m_prologText; + string m_epilogText; +}; + + +} // vmime + + +#endif // VMIME_GENERATIONCONTEXT_HPP_INCLUDED diff --git a/vmime/header.hpp b/vmime/header.hpp index 6f5bf6d7..cb44c41d 100644 --- a/vmime/header.hpp +++ b/vmime/header.hpp @@ -263,14 +263,15 @@ protected: // Component parsing & assembling void parseImpl - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); void generateImpl - (utility::outputStream& os, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; }; diff --git a/vmime/headerField.hpp b/vmime/headerField.hpp index cfc1252e..857ee051 100644 --- a/vmime/headerField.hpp +++ b/vmime/headerField.hpp @@ -121,20 +121,22 @@ public: protected: void parseImpl - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); void generateImpl - (utility::outputStream& os, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; static ref <headerField> parseNext - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); diff --git a/vmime/mailbox.hpp b/vmime/mailbox.hpp index 06305f4e..ec071db3 100644 --- a/vmime/mailbox.hpp +++ b/vmime/mailbox.hpp @@ -25,6 +25,7 @@ #define VMIME_MAILBOX_HPP_INCLUDED +#include "vmime/emailAddress.hpp" #include "vmime/address.hpp" #include "vmime/text.hpp" @@ -45,8 +46,8 @@ public: mailbox(); mailbox(const mailbox& mbox); - mailbox(const string& email); - mailbox(const text& name, const string& email); + mailbox(const emailAddress& email); + mailbox(const text& name, const emailAddress& email); /** Return the full name of the mailbox (empty if not specified). * @@ -64,13 +65,13 @@ public: * * @return email of the mailbox */ - const string& getEmail() const; + const emailAddress& getEmail() const; /** Set the email of the mailbox. * * @param email email of the mailbox */ - void setEmail(const string& email); + void setEmail(const emailAddress& email); // Comparison bool operator==(const class mailbox& mailbox) const; @@ -93,7 +94,7 @@ public: protected: text m_name; - string m_email; + emailAddress m_email; public: @@ -102,14 +103,15 @@ public: // Component parsing & assembling void parseImpl - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); void generateImpl - (utility::outputStream& os, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; }; diff --git a/vmime/mailboxField.hpp b/vmime/mailboxField.hpp index ca281415..55368643 100644 --- a/vmime/mailboxField.hpp +++ b/vmime/mailboxField.hpp @@ -52,7 +52,9 @@ protected: public: - void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); + void parse(const parsingContext& ctx, const string& buffer, + const string::size_type position, const string::size_type end, + string::size_type* newPosition = NULL); }; diff --git a/vmime/mailboxGroup.hpp b/vmime/mailboxGroup.hpp index 09567798..509e06b7 100644 --- a/vmime/mailboxGroup.hpp +++ b/vmime/mailboxGroup.hpp @@ -169,14 +169,15 @@ protected: // Component parsing & assembling void parseImpl - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); void generateImpl - (utility::outputStream& os, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; }; diff --git a/vmime/mailboxList.hpp b/vmime/mailboxList.hpp index 987d6a8f..d08cf2bb 100644 --- a/vmime/mailboxList.hpp +++ b/vmime/mailboxList.hpp @@ -159,14 +159,15 @@ protected: // Component parsing & assembling void parseImpl - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); void generateImpl - (utility::outputStream& os, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; }; diff --git a/vmime/mediaType.hpp b/vmime/mediaType.hpp index b929f0db..866810fa 100644 --- a/vmime/mediaType.hpp +++ b/vmime/mediaType.hpp @@ -99,14 +99,15 @@ protected: // Component parsing & assembling void parseImpl - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); void generateImpl - (utility::outputStream& os, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; }; diff --git a/vmime/message.hpp b/vmime/message.hpp index 3c70e52d..ebb767e7 100644 --- a/vmime/message.hpp +++ b/vmime/message.hpp @@ -26,7 +26,7 @@ #include "vmime/bodyPart.hpp" -#include "vmime/options.hpp" +#include "vmime/generationContext.hpp" namespace vmime @@ -42,26 +42,16 @@ public: message(); - public: + using bodyPart::parse; + using bodyPart::generate; + // Override default generate() functions so that we can change // the default 'maxLineLength' value - void generate - (utility::outputStream& os, - const string::size_type maxLineLength = options::getInstance()->message.maxLineLength(), - const string::size_type curLinePos = 0, - string::size_type* newLinePos = NULL) const; - const string generate - (const string::size_type maxLineLength = options::getInstance()->message.maxLineLength(), + (const string::size_type maxLineLength = generationContext::getDefaultContext().getMaxLineLength(), const string::size_type curLinePos = 0) const; - - void generate - (ref <utility::outputStream> os, - const string::size_type maxLineLength = lineLengthLimits::infinite, - const string::size_type curLinePos = 0, - string::size_type* newLinePos = NULL) const; }; diff --git a/vmime/messageId.hpp b/vmime/messageId.hpp index cfca9cfb..b8c4693f 100644 --- a/vmime/messageId.hpp +++ b/vmime/messageId.hpp @@ -108,14 +108,15 @@ protected: // Component parsing & assembling void parseImpl - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); void generateImpl - (utility::outputStream& os, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; @@ -128,7 +129,8 @@ protected: * @return a new message-id object, or null if no more message-id can be parsed from the input buffer */ static ref <messageId> parseNext - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition); diff --git a/vmime/messageIdSequence.hpp b/vmime/messageIdSequence.hpp index 1d1f9509..8ec7292a 100644 --- a/vmime/messageIdSequence.hpp +++ b/vmime/messageIdSequence.hpp @@ -152,14 +152,15 @@ protected: // Component parsing & assembling void parseImpl - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); void generateImpl - (utility::outputStream& os, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; }; diff --git a/vmime/parameter.hpp b/vmime/parameter.hpp index 546600d0..82314575 100644 --- a/vmime/parameter.hpp +++ b/vmime/parameter.hpp @@ -125,20 +125,21 @@ public: protected: void parseImpl - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); void generateImpl - (utility::outputStream& os, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; private: - void parse(const std::vector <valueChunk>& chunks); + void parse(const parsingContext& ctx, const std::vector <valueChunk>& chunks); string m_name; diff --git a/vmime/parameterizedHeaderField.hpp b/vmime/parameterizedHeaderField.hpp index b3f8fc43..ee54d0a2 100644 --- a/vmime/parameterizedHeaderField.hpp +++ b/vmime/parameterizedHeaderField.hpp @@ -181,14 +181,15 @@ private: protected: void parseImpl - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); void generateImpl - (utility::outputStream& os, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; }; diff --git a/vmime/parsingContext.hpp b/vmime/parsingContext.hpp new file mode 100644 index 00000000..0ca194c5 --- /dev/null +++ b/vmime/parsingContext.hpp @@ -0,0 +1,59 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 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 3 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. +// + +#ifndef VMIME_PARSINGCONTEXT_HPP_INCLUDED +#define VMIME_PARSINGCONTEXT_HPP_INCLUDED + + +#include "vmime/context.hpp" + + +namespace vmime +{ + + +/** Holds configuration parameters used for parsing messages. + */ + +class parsingContext : public context +{ +public: + + parsingContext(); + parsingContext(const parsingContext& ctx); + + /** Returns the default context used for parsing messages. + * + * @return a reference to the default parsing context + */ + static parsingContext& getDefaultContext(); + +protected: + +}; + + +} // vmime + + +#endif // VMIME_PARSINGCONTEXT_HPP_INCLUDED diff --git a/vmime/path.hpp b/vmime/path.hpp index 1fb58384..d2077857 100644 --- a/vmime/path.hpp +++ b/vmime/path.hpp @@ -86,14 +86,15 @@ protected: // Component parsing & assembling void parseImpl - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); void generateImpl - (utility::outputStream& os, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; }; diff --git a/vmime/relay.hpp b/vmime/relay.hpp index 96e021c6..20547d98 100644 --- a/vmime/relay.hpp +++ b/vmime/relay.hpp @@ -88,14 +88,15 @@ private: protected: void parseImpl - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); void generateImpl - (utility::outputStream& os, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; }; diff --git a/vmime/text.hpp b/vmime/text.hpp index 7ead7d6b..83281200 100644 --- a/vmime/text.hpp +++ b/vmime/text.hpp @@ -135,9 +135,11 @@ public: * specified destination charset. * * @param dest output charset + * @param opts options for charset conversion * @return text decoded in the specified charset */ - const string getConvertedText(const charset& dest) const; + const string getConvertedText(const charset& dest, + const charsetConverterOptions& opts = charsetConverterOptions()) const; /** Return the unconverted (raw) data of all words. This is the * concatenation of the results returned by getBuffer() on @@ -194,21 +196,23 @@ public: FORCE_NO_ENCODING = (1 << 0), /**< Just fold lines, don't encode them. */ FORCE_ENCODING = (1 << 1), /**< Encode lines even if they are plain ASCII text. */ NO_NEW_LINE_SEQUENCE = (1 << 2), /**< Use CRLF instead of new-line sequence (CRLF + TAB). */ - QUOTE_IF_POSSIBLE = (1 << 3) /**< Use quoting instead of encoding when possible (even if FORCE_ENCODING is specified). */ + QUOTE_IF_POSSIBLE = (1 << 3), /**< Use quoting instead of encoding when possible (even if FORCE_ENCODING is specified). */ + QUOTE_IF_NEEDED = (1 << 4) /**< Use quoting instead of encoding if needed (eg. whitespaces and/or special chars). */ }; /** Encode and fold text in respect to RFC-2047. * + * @param ctx generation context * @param os output stream * @param maxLineLength maximum line length for output * @param firstLineOffset the first line length (may be useful if the current output line is not empty) * @param lastLineLength will receive the length of the last line written * @param flags encoding flags (see EncodeAndFoldFlags) */ - void encodeAndFold(utility::outputStream& os, const string::size_type maxLineLength, + void encodeAndFold(const generationContext& ctx, utility::outputStream& os, const string::size_type firstLineOffset, string::size_type* lastLineLength, const int flags) const; - /** Decode and unfold text (RFC-2047). + /** Decode and unfold text (RFC-2047), using the default parsing context. * * @param in input string * @return new text object @@ -217,6 +221,14 @@ public: /** Decode and unfold text (RFC-2047). * + * @param ctx parsingContext + * @param in input string + * @return new text object + */ + static ref <text> decodeAndUnfold(const parsingContext& ctx, const string& in); + + /** Decode and unfold text (RFC-2047), using the default parsing context. + * * @param in input string * @param generateInExisting if not NULL, the resulting text will be generated * in the specified object instead of a new created object (in this case, the @@ -226,18 +238,31 @@ public: */ static text* decodeAndUnfold(const string& in, text* generateInExisting); + /** Decode and unfold text (RFC-2047). + * + * @param ctx parsing context + * @param in input string + * @param generateInExisting if not NULL, the resulting text will be generated + * in the specified object instead of a new created object (in this case, the + * function returns the same pointer). Can be used to avoid copying the + * resulting object into an existing object. + * @return new text object or existing object if generateInExisting != NULL + */ + static text* decodeAndUnfold(const parsingContext& ctx, const string& in, text* generateInExisting); + protected: // Component parsing & assembling void parseImpl - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); void generateImpl - (utility::outputStream& os, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; diff --git a/vmime/utility/stringUtils.hpp b/vmime/utility/stringUtils.hpp index 535e6905..7fcdc622 100644 --- a/vmime/utility/stringUtils.hpp +++ b/vmime/utility/stringUtils.hpp @@ -104,6 +104,14 @@ public: */ static string::size_type countASCIIchars(const string::const_iterator begin, const string::const_iterator end); + /** Returns whether the specified string is composed exclusively + * of 7-bit ASCII characters. + * + * @param str string to test + * @return true if the string is ASCII-only, false otherwise + */ + static bool is7bit(const string& str); + /** Returns the position of the first non 7-bit US-ASCII character in a string. * * @param begin start position @@ -153,6 +161,25 @@ public: * @return unquoted string */ static const string unquote(const string& str); + + /** Determines whether the specified string needs to be quoted. + * + * @param str string to test + * @param specialChars list of characters that will cause the + * string to be quoted + * @return true if the string needs to be quoted, false otherwise + */ + static bool needQuoting(const string& str, + const string& specialChars = " \t\"(),:;<>@[\\]"); + + /** Quotes the specified string. + * + * @param str string to quote + * @param escapeSpecialChars list of characters that will be escaped + * @param escapeChar character that will be used for escaping (eg. '\') + * @return quoted string + */ + static string quote(const string& str, const string& escapeSpecialChars, const string& escapeChar); }; diff --git a/vmime/vmime.hpp b/vmime/vmime.hpp index bb140354..e7dd3959 100644 --- a/vmime/vmime.hpp +++ b/vmime/vmime.hpp @@ -31,7 +31,6 @@ // Base definitions #include "vmime/base.hpp" #include "vmime/exception.hpp" -#include "vmime/options.hpp" #include "vmime/platform.hpp" // Base components @@ -42,6 +41,7 @@ #include "vmime/text.hpp" #include "vmime/encoding.hpp" #include "vmime/contentDisposition.hpp" +#include "vmime/emailAddress.hpp" #include "vmime/mailbox.hpp" #include "vmime/mailboxGroup.hpp" #include "vmime/mailboxList.hpp" @@ -57,6 +57,9 @@ #include "vmime/stringContentHandler.hpp" #include "vmime/streamContentHandler.hpp" +#include "vmime/generationContext.hpp" +#include "vmime/parsingContext.hpp" + // Message components #include "vmime/message.hpp" diff --git a/vmime/word.hpp b/vmime/word.hpp index 5d350fa4..73312f6c 100644 --- a/vmime/word.hpp +++ b/vmime/word.hpp @@ -27,6 +27,7 @@ #include "vmime/headerFieldValue.hpp" #include "vmime/charset.hpp" +#include "vmime/charsetConverterOptions.hpp" namespace vmime @@ -94,9 +95,11 @@ public: /** Return the contained text converted to the specified charset. * * @param dest output charset + * @param opts options for charset conversion * @return word converted to the specified charset */ - const string getConvertedText(const charset& dest) const; + const string getConvertedText(const charset& dest, + const charsetConverterOptions& opts = charsetConverterOptions()) const; /** Replace data in this word by data in other word. * @@ -131,14 +134,15 @@ public: protected: void parseImpl - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); void generateImpl - (utility::outputStream& os, - const string::size_type maxLineLength = lineLengthLimits::infinite, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; @@ -148,8 +152,8 @@ public: #ifndef VMIME_BUILDING_DOC void generate - (utility::outputStream& os, - const string::size_type maxLineLength, + (const generationContext& ctx, + utility::outputStream& os, const string::size_type curLinePos, string::size_type* newLinePos, const int flags, @@ -161,7 +165,8 @@ public: private: static ref <word> parseNext - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition, @@ -170,7 +175,8 @@ private: bool isFirst); static const std::vector <ref <word> > parseMultiple - (const string& buffer, + (const parsingContext& ctx, + const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition); diff --git a/vmime/wordEncoder.hpp b/vmime/wordEncoder.hpp index e43b7edb..acaef791 100644 --- a/vmime/wordEncoder.hpp +++ b/vmime/wordEncoder.hpp @@ -75,11 +75,12 @@ public: /** Test whether RFC-2047 encoding is needed. * + * @param ctx generation context * @param buffer buffer to analyze * @param charset charset of the buffer * @return true if encoding is needed, false otherwise. */ - static bool isEncodingNeeded(const string& buffer, const charset& charset); + static bool isEncodingNeeded(const generationContext& ctx, const string& buffer, const charset& charset); /** Guess the best RFC-2047 encoding to use for the specified buffer. * |