Program: Creating a Multipart MIME Message
Example 29 presents a complete program that creates a multipart MIME message. The program creates a multipart message that contains the same text in three formats: unencoded, base 64 encoded, and quoted-printable encoded. Source code for this program is located in MultipartMimeMessageComposition.cpp in the examples\mime directory.
NOTE: Sample programs are located in the examples directory created for your installation. For more information, see Installing and Building Your SourcePro Products and Building Your Applications.
Example 29 – Creating a multipart MIME message
#include <rw/mime/RWMimeMultipart.h>
#include <rw/mime/RWMimeMultipartType.h>
#include <rw/mime/RWMimePart.h>
#include <rw/mime/RWMimeTextType.h>
#include <rw/mime/RWMimeContentTransferEncodingHeader.h>
#include <rw/mime/RWMimeUtils.h>
#include <rw/mime/RWMimeGenericHeader.h>
#include <rw/mime/RWMimeVersionHeader.h>
 
#include <iostream>
using std::cout;
using std::endl;
 
int main(void)
{
// Generate the headers that we will use for the inner parts
// of the message. All parts will be in plain text.
RWMimeTextType textType("plain"); //1
 
// We need Content-Transfer-Encoding headers for the two
// messages that are encoded.
RWMimeContentTransferEncodingHeader
base64CTE(RWMimeUtils::Base64); //2
RWMimeContentTransferEncodingHeader
qpCTE(RWMimeUtils::QuotedPrintable); //3
// The parts will need a body to be sent.
RWCString partBody("This is a part in a (multipart) message "
"generated with the Rogue Wave SourcePro "
"Net product.\n"
"\n"
"All of the parts of this message are "
"identical, however they've been encoded "
"for transport using different methods."
"\n"); //4
 
// convert the body of the message to canonical form before
// transmitting or encoding.
partBody = RWMimeUtils::replaceLineDelimiter(partBody); //5
// Now we need to encode the body of the message from
// transport. For this example, we'll encode the same message
// using base64 and quoted-printable encodings.
RWCString partBodyBase64 =
RWMimeUtils::encode(partBody, RWMimeUtils::Base64); //6
RWCString partBodyQP =
RWMimeUtils::encode(partBody,
RWMimeUtils::QuotedPrintable); //7
// Now we are ready to create the individual parts of the
// message. For this example, there will be three parts. One
// unencoded, one encoded using base64, and one encoded
// using quoted-printable.
RWMimePart part1(textType),
part2(textType),
part3(textType); //8
// unencoded part
part1.setBody(partBody); //9
 
// base64 encoded
part2.insertHeader(base64CTE); //10
part2.setBody(partBodyBase64); //11
 
// quoted-printable encoded
part3.insertHeader(qpCTE); //12
part3.setBody(partBodyQP); //13
RWMimeMultipartType multipartType("mixed"); //14
// Create the basic message object. This will hold all of the message
// parts, and format them according to the MIME specification.
RWMimeMultipart message(multipartType); //15
// Generate the headers required for the main message.
// Use a generic header to create headers that don't have a
// derived header type.
RWMimeGenericHeader toHeader("To",
"<developer@yourcompany.com>"); //16
RWMimeGenericHeader fromHeader("From",
"<developer@roguewave.com>");
RWMimeGenericHeader subjectHeader("Subject",
"Sample MIME Multipart Message from Rogue Wave");
// Add each of the headers to the message.
message.insertHeader(RWMimeVersionHeader()); //17
message.insertHeader(toHeader); //18
message.insertHeader(fromHeader);
message.insertHeader(subjectHeader);
 
// We'll also want to send a preamble to the message for
// user agents that don't recognize MIME.
RWCString preamble(
"This is a MIME 1.0 compliant message.\n"
"\n"
"If you are able to see this message, your\n"
"user agent is not MIME compliant. You will\n"
"need an alternative mail viewer to read this\n"
"message in its entirety.\n"); //19
preamble = RWMimeUtils::replaceLineDelimiter(preamble); //20
message.setPreamble(preamble); //21
// Insert each of the parts into the multipartBody.
message.insertPart(part1); //22
message.insertPart(part2);
message.insertPart(part3);
// The message is ready to go. Normally you would send this
// through a protocol (SMTP, HTTP), but for this example we
// will just print it to stdout.
 
cout << message.asString() << endl; //23
return 0;
}
//1 Creates an RWMimeTextType for the value "text/plain".
//2 Constructs a Content-Transfer-Encoding header for base 64 encoding.
//3 Constructs a Content-Transfer-Encoding header for quoted-printable encoding.
//4 Constructs the string that forms the basic content for each part of the multipart message.
//5 Converts the content string to canonical form.
//6 Encodes the content string using base 64 encoding and stores the result in a new string.
//7 Encodes the content string using quoted-printable encoding and stores the result in a new string.
//8 Constructs three new RWMimePart objects. Each object has a Content-Type header with the value textType.
//9 Sets the body of the first MIME part to the unencoded content.
//10 Inserts the Content-Transfer-Encoding header for base 64 encoding into the second MIME part.
//11 Sets the body of the second MIME part to the base 64 encoded content.
//12 Inserts the Content-Type header for text/plain into the third MIME part.
//13 Inserts the Content-Transfer-Encoding header for quoted-printable encoding into the third MIME part.
//14 Constructs an RWMimeMultipartType for multipart/mixed content. The constructor automatically generates a boundary string.
//15 Constructs an RWMimeMultipart with the multipart/mixed C-ontent‑Type created on line //14.
//16 Each of the next three lines creates an email header for the MIME message. The headers are instances of RWMimeGenericHeader. The MIME package provides RWMimeGenericHeader for headers that are not part of the MIME specification.
//17 Inserts a MIME-Version header into the part. A MIME message requires a MIME-Version header. A default-constructed RWMimeVersionHeader contains the correct version number.
//18 Each of the next three lines inserts a header into the part.
//19 Creates a preamble for the multipart message. Although the MIME specification doesn’t require a multipart message to contain a preamble, most multipart messages provide one.
//20 Converts the preamble to canonical form.
//21 Sets the preamble of the multipart body.
//22 Each of the next three lines inserts a MIME part into the multipart body.
//23 Prints the message to standard output. A production application would typically enclose the asString() function in a try block, since the function throws an RWMimeError if it can’t create a MIME string with the correct syntax. Since this example uses a constant string, we’ve left out the try block for clarity.
The exact output of the program varies since the automatically-generated boundary string includes a timestamp. Further, we’ve wrapped some of the longer lines. Taking those differences into account, the output of the program is similar to:
 
Content-Type: multipart/mixed; boundary="_=_next_part_-560821453_=_"
MIME-Version: 1.0
To: <developer@yourcompany.com>
From: <developer@roguewave.com>
Subject: Sample MIME Multipart Message from Rogue Wave
 
This is a MIME 1.0 compliant message.
 
If you are able to see this message, your
user agent is not MIME compliant. You will
need an alternative mail viewer to read this
message in its entirety.
 
--_=_next_part_-560821453_=_
Content-Type: text/plain
 
This is a part in a (multipart) message generated with the Rogue Wave
SourcePro Net product.
 
All of the parts of this message are identical, however they've been
encoded for transport using different methods.
 
--_=_next_part_-560821453_=_
Content-Type: text/plain
Content-Transfer-Encoding: base64
 
VGhpcyBpcyBhIHBhcnQgaW4gYSAobXVsdGlwYXJ0KSBtZXNzYWdlIGdlbmVyYXRlZCB3aXRo
IHRoZSBSb2d1ZSBXYXZlIFNvdXJjZVBybyBOZXQgcHJvZHVjdC4NCg0KQWxsIG9mIHRoZSBw
YXJ0cyBvZiB0aGlzIG1lc3NhZ2UgYXJlIGlkZW50aWNhbCwgaG93ZXZlciB0aGV5J3ZlIGJl
ZW4gZW5jb2RlZCBmb3IgdHJhbnNwb3J0IHVzaW5nIGRpZmZlcmVudCBtZXRob2RzLg0K
--_=_next_part_-560821453_=_
Content-Type: text/plain
Content-Transfer-Encoding: quoted-printable
 
This is a part in a (multipart) message generated with the Rogue Wave Sour=
cePro Net product.
 
All of the parts of this message are identical, however they've been encod=
ed for transport using different methods.
 
--_=_next_part_-560821453_=_--