classPiiMultipartDecoder
#include <PiiMultipartDecoder.h>
A class that decodes MIME multipart messages.
Inherits QIODevice
Description
PiiMultipartDecoder is an IO device that decodes a multipart MIME message and splits the input stream into chunks based on the extracted information. Once a header has been fetched, read operations will be terminated to the next boundary of the multipart message body. The class recognizes nested multiparts.
Consider the following multipart MIME message (example from http://www.w3.org/TR/html401/interact/forms.html):
Content-Type: multipart/form-data; boundary=AaB03x --AaB03x Content-Disposition: form-data; name="submit-name" Larry --AaB03x Content-Disposition: form-data; name="files" Content-Type: multipart/mixed; boundary=BbC04y --BbC04y Content-Disposition: file; filename="text.txt" Content-Type: text/plain ... contents of text.txt ... --BbC04y Content-Disposition: file; filename="image.png" Content-Type: image/png Content-Transfer-Encoding: binary ...contents of image.png... --BbC04y-- --AaB03x--
The code to read the message is as follows:
// Assume you have a tcp connection through "socket" PiiMultipartDecoder decoder(socket); while (decoder.nextMessage()) { // Read body contents QByteArray aBody = decoder.readAll(); if (decoder.header().contentType() == "image/png") decodePngImage(aBody); }
The decoder will read the topmost header first. Since the header
represents a multipart message, the header of the first body part
will also be read. After the first call to #bodyPartHeader(), there
will be two headers on the header stack (depth() will return 2). The first call to
readAll() will return "Larry".
The next round will also read two headers because the message
contains a nested multipart message (depth() will return 3). The second
readAll() call will return the contents of file1.txt.
The third round fetches the contents of file2.gif, after which the
loop will break.
Constructors and destructor
|
Create a new multipart message decoder with a header that has already been read from the input device. |
|
|
Create a new multipart message decoder. |
|
Public member functions
|
qint64
|
( )
|
|
int
|
( )
Returns the depth of the current body part stack. |
|
(
Returns the header of a nested body part. |
|
|
bool
|
( )
|
|
bool
|
( )
Reads headers from the input stream until an ordinary (non-multipart) message header is found and puts all read headers into the header stack. |
Protected member functions
|
qint64
|
(
Reads data from the underlying device. |
|
qint64
|
(
Writes data to the underlying device. |
Function details
-
PiiMultipartDecoder
Create a new multipart message decoder with a header that has already been read from the input device.
void MyHandler::handleRequest(const QString& uri, PiiHttpDevice* h, PiiProgressController* controller) { if (!h->readHeader()) return; if (h->requestMethod() == "POST" && h->requestHeader().contentType().startsWith("multipart/")) { PiiMultipartDecoder decoder(h, h->requestHeader()); // Read message preamble decoder.readAll(); while (decoder.nextMessage()) { // ... } } }
-
PiiMultipartDecoder
Create a new multipart message decoder.
This constructor assumes that the message header has not been read yet.
-
~PiiMultipartDecoder
() -
qint64 bytesAvailable
() -
int depth
()Returns the depth of the current body part stack.
The depth increases with each nesting level inside multipart messages. The preamble of the first-level multipart message is at depth one, and the first entity within the message is at depth two.
-
PiiMimeHeader header
(- int level = 0
Returns the header of a nested body part.
The bottommost header in the stack is either the one given in the constructor or the first one read from the input strem. If the body is a multipart message as of RFC 2387, more headers will be added to the stack when the message body is being parsed. Once all body parts have been read, the body part stack will be emptied.
Since a multipart message can contain another multipart message, the depth of the header stack can be arbitrary. The
levelparameter can be used to obtain information about enclosing messages. If there are no more body parts, or an incorrectlevelis given, an invalid header will be returned.Parameters
- level
-
the stacking level. 0 refers to the body part the device is currently reading, 1 is its parent and so on.
Returns
a MIME header or an invalid header if there is no such level.
-
bool isSequential
() -
bool nextMessage
()Reads headers from the input stream until an ordinary (non-multipart) message header is found and puts all read headers into the header stack.
Headers can only be read once all the data in a message body has been read.
Returns
trueif a message was successfully read,falseif no more messages could be read.Exceptions
- PiiMimeException&
-
if the header is incorrectly encoded
-
qint64 readData
(- char * data
- qint64 maxSize
[protected]Reads data from the underlying device.
Stops at message boundaries.
-
qint64 writeData
(- const char * data
- qint64 maxSize
[protected]Writes data to the underlying device.
Provided just for completeness. Decoders aren't often used for writing.
Add a note
Not a single note added yet. Be the first, add yours.