examples/mimeencoder.C
is an example of creating encoded MIME entities.
mimeencoder.C
takes a list of filenames as parameters,
and creates a list of MIME entities, one entity
per file, with its contents; then
creates a multipart MIME entity consisting of all the
individual MIME entities.
MIME entities get constructed from a
x::headersimpl<x::headersbase::lf_endl>
or a
x::headersimpl<x::headersbase::crlf_endl>
object, and additional parameters that define the content of the entity.
The selection of the x::headersimpl
specialization determines whether MIME encoding uses
LF
or CRLF
newline sequence for
the encoded header and body portion of the MIME entity.
#include <x/mime/structured_content_header.H> #include <x/mime/encoder.H> std::string filename; x::headersimpl<x::headersbase::lf_endl> headers; x::mime::structured_content_header content_type(x::mime::filetype(x::mime::from_file(filename)); if (content_type.mime_content_type() == "text") content_type("charset", x::mime::filecharset(filename)); content_type.append(headers, x::mime::content_type); x::mime::structured_content_header("attachment") .rfc2231("filename", filename, "UTF-8") .append(headers, x::mime::structured_content_header::content_disposition); x::mime::encoder section= x::mime::make_section(headers, x::mime::from_file(filename)));
Encoding a MIME entity begins by constructing
structured
“Content-Type”, and, perhaps,
“Content-Disposition” MIME headers, with the
help of
x::mime::filetype
() and
x::mime::filecharset
().
x::mime::filetype
() takes a filename argument,
and searches for a registered MIME type for that filename extension
in mime.types
. If the extension is not found,
the MIME type gets heuristically derived from the contents of the file
using libmagic, a.k.a. the
file(1)
command.
Alternatively, x::mime::filetype
() also takes
a file descriptor in place of a filename,
which does only the content file lookup.
For text
MIME content, if the character set is not
known otherwise,
x::mime::filecharset
() also derives it
heuristically via libmagic.
x::mime::make_section
()
takes a constructed header parameter, that
specifies a completed set of MIME headers, and
a container that specifies the raw, unencoded contents of the
MIME entity, and returns
a
x::mime::encoder
.
This is a reference to a
reference-counted object that represents
an encoded MIME entity.
x::mime::make_section
()'s second parameter
is any container that implements begin
() and
end
() that define the beginning and the
iterator for an input, forward, or a random access sequence of
char
s that give the unencoded
contents of the MIME entity.
The container must be copy-constructible.
x::mime::fromfile
()
supplies a suitable container that reads the contents of the
MIME section from a file, specified as a filename or
a file descriptor object.
std::copy(section->begin(), section->end(), std::ostreambuf_iterator<char>(std::cout));
x::mime::encoder
's referenced object's
begin
() and end
() return
a x::mime::encoder::base::iterator
, defining
a beginning and an ending iterator for an input sequence of
char
s containing the headers followed by the encoded
contents of the MIME section.
x::mime::make_section
() does
not read the
entire contents of the MIME entity and encodes it,
and gives back a x::mime::encoder
that returns
the iterators to the encoded sequence.
x::mime::make_section
() copies the headers parameter
and the container object itself, into the
the x::mime::encoder
object.
begin
() and end
()
call the container's
begin
() and end
(),
and encode the object on the fly (together with preceding
MIME headers).
In other words, a
x::mime::fromfile
referencing a ten megabyte file
does not load the entire contents of the file into memory. The file
gets opened by
begin
() and end
(),
and gets encoded on the fly.
A x::mime::fromfile
specifying a file
descriptor to a non-regular file, such as a pipe, results in
x::mime::fromfile
reading its entire contents
into a temporary file. Specifying a filename simply opens the file,
directly.
x::mime::encoder section= x::mime::make_section(headers, x::mime::from_file(filename), false, 255));
x::mime::make_section
() selects the
transfer encoding heuristically, by reading the container and
selecting 7bit
, 8bit
,
quoted-printable
, or base64
.
x::mime::make_section
() takes two optional
parameters.
An optional bool
parameter has a default value
of false
. Setting it to true
disables 8bit
, and forces either
quoted-printable
or base64
, if
7bit
does not work.
A maximum size of each text line has a default value of
76. Even if the MIME entity does not need
quoted-printable
or base64
otherwise, they get used if the MIME entity contains lines that
exceed the text line size parameter, and the parameter specifies
the maximum size of the lines in the encoded content, as well.
x::mime::encoder section= x::mime::make_base64_section(headers, x::mime::from_file(filename))); x::mime::encoder section= x::mime::make_qp_section(headers, x::mime::from_file(filename)));
x::mime::make_base64_section
()
and
x::mime::make_qp_section
()
explicitly construct a base64
or a
quoted-printable
-encoded MIME entity.
An optional parameter gives the maximum line size of the encoded entity,
defaulting to 76 characters per line.
x::mime::make_section
(),
x::mime::make_base64_section
(), and
x::mime::make_qp_section
()
supply the appropriate “Content-Transfer-Encoding”
header, and this header should not be present in the
x::headersimpl
parameter.
There's also a
x::mime::make_plain_section
()
that constructs a
x::mime::encoder
that does not perform
any MIME encoding, presuming that 7bit
or 8bit
works for the MIME entity.
x::mime::make_plain_section
()
does not supply a “Content-Transfer-Encoding” header.
If required, it needs to be added to the headers parameter.
x::headersimpl<x::headersbase::lf_endl> headers; headers.append("Mime-Version", "1.0"); headers.append("Subject", "test"); auto section1=x::mime::make_section(headers, std::string("Hello world!\n")); headers.clear(); auto section2=x::mime::make_message_rfc822_section(headers, section1);
x::mime::make_message_rfc822_section
()
takes a previously-created encoder of an entire message, and constructs
a message/rfc822 entity from it.
x::mime::make_message_rfc822_section
adds
“Content-Type: message/rfc822” header to any headers
present in its headers
parameter.