9.4 Creating a Multipart MIME Part
MIME parts often contain more than one document within a single part. Each document contained in a multipart part is a complete MIME part or MIME message. Therefore, the MIME specification refers to messages that contain multiple documents as multipart parts. This section describes the step-by-step process for creating a multipart/mixed part, a multipart type typically used for email attachments. The process for other multipart content types is similar.
To create a multipart/mixed message:
1. Create a MIME part for each part of the message containing the data. The steps for creating a simple MIME part are described in Section 9.2, “Creating a Simple MIME Part.”
2. Create headers for a multipart (Section 9.4.2).
3. Create an RWMimeMultipart (Section 9.4.3).
4. Add each part to the multipart body (Section 9.4.4).
5. Add the headers to the message (Section 9.4.5).
6. Create a MIME string (Section 9.4.6).
Section 9.5, “Program: Creating a Multipart MIME Message,” presents a complete example program that creates a multipart MIME message.
9.4.1 Create Parts
Each part of a multipart is a complete, valid MIME part. Construct MIME parts as described in Section 9.2, “Creating a Simple MIME Part,” above.
Some multipart types require that the parts contain specific headers. For example, a multipart/related message requires each MIME part the message contains to have either a Content-ID or a Content-Location header. See RFC 2387 for details on the multipart/related content type.
9.4.2 Create Headers for a Multipart
Every multipart must contain a Content-Type header. The header must have a boundary string, and the boundary string must match the boundary string in the multipart body of the message. Create a Content-Type header as shown below:
 
RWMimeMultipartType mixed;
RWMimeContentTypeHeader cTHead(mixed);
The default constructor for an RWMimeMultipartType creates a multipart/mixed type with a boundary string created by the getUniqueBoundaryString() function of RWMimeUtils. To create a value with a different subtype, provide the subtype to the constructor. For example, the line below creates a multipart/alternative Content-Type value with an automatically-generated boundary parameter:
 
RWMimeMultipartType alternative("alternative");
MIME requires that a message contain a MIME-Version header. Construct an RWMimeVersionHeader.
 
RWMimeVersionHeader version;
The Content-Transfer-Encoding for a multipart message must be one of the identity encoded types – either 7bit, 8bit, or binary. To determine the Content-Transfer-Encoding:
*If any of the parts to be included in the message has a Content-Transfer-Encoding of binary, use binary.
*Otherwise, if any of the parts to be included in the message has a Content-Transfer-Encoding of 8bit, use 8bit.
*Otherwise, use 7bit.
MIME parts often require protocol-specific headers in addition to MIME headers. For example, email messages require a Date header and a From header. The RWMimeGenericHeader class represents a general-purpose header. If the part requires headers that aren’t part of the MIME format, use instances of RWMimeGenericHeader for those headers. For example, the line below creates a From header for an email message:
 
RWMimeGenericHeader from("From:", "Dev <developer@roguewave.com>");
9.4.3 Create an RWMimeMultipart
Construct the part as an instance of RWMimeMultipart:
 
RWMimeMultipart multipartMessage;
Although a multipart is not required to contain a preamble, most multipart messages that contain human-readable content provide one. Set the preamble using the setPreamble() function:
 
multipartBody.setPreamble("This is a MIME message.\r\n"
"\r\n"
"If you see this message, your user"
"agent is not MIME-compliant\r\n");
9.4.4 Add Each Part
Use the insertPart() function of RWMimeMultipart to add each MIME part to the multipart:
 
RWMimePart part1;
 
// ... fill part1 with content.
 
RWMimePart part2;
 
// ... fill part2 with content.
 
RWMimeMultipart multipartMessage;
 
multipartMessage.insertPart(part1);
multipartMessage.insertPart(part2);
Add the parts in the order in which they should appear in the multipart.
An RWMimeMultipart must not contain itself, either directly or indirectly. A part that contains itself cannot be represented as a string.
9.4.5 Add Headers to the Part
Add the headers to the part using insertHeader() as shown below:
 
multipartMessage.insertHeader(mixed);
multipartMessage.insertHeader(version);
multipartMessage.insertHeader(from);
Remember that a multipart must contain a Content-Type header with a multipart media type, and that every MIME message must contain a MIME-Version header.
9.4.6 Create a MIME String
The MIME part is now complete and ready to use. To send the message over a network, convert the message into a MIME string using the asString() function, as shown:
 
RWMimeMultipart multipartMessage;
 
// ... fill message as described above
 
RWCString msgString;
 
try
{
msgString = multipartMessage.asString();
}
catch (const RWMimeError& msg)
{
// Handle the error
}
The asString() function doesn’t enforce a particular part style, or even guarantee that the part is correct MIME. The function does contain some safeguards that prevent a program from generating an unintelligible message. If the function cannot produce a structurally correct MIME message, the function throws RWMimeError.