## CamelMimeParser

CamelMimeParser

## Synopsis

    struct              CamelMimeParser;
    enum                camel_mime_parser_state_t;
    CamelMimeParser *   camel_mime_parser_new               (void);
    gint                camel_mime_parser_errno             (CamelMimeParser *parser);
    gint                camel_mime_parser_init_with_fd      (CamelMimeParser *m,
                                                             gint fd);
    gint                camel_mime_parser_init_with_stream  (CamelMimeParser *m,
                                                             CamelStream *stream,
                                                             GError **error);
    void                camel_mime_parser_init_with_input_stream
                                                            (CamelMimeParser *parser,
                                                             GInputStream *input_stream);
    void                camel_mime_parser_init_with_bytes   (CamelMimeParser *parser,
                                                             GBytes *bytes);
    CamelStream *       camel_mime_parser_stream            (CamelMimeParser *parser);
    void                camel_mime_parser_scan_from         (CamelMimeParser *parser,
                                                             gboolean scan_from);
    void                camel_mime_parser_scan_pre_from     (CamelMimeParser *parser,
                                                             gboolean scan_pre_from);
    gint                camel_mime_parser_set_header_regex  (CamelMimeParser *parser,
                                                             gchar *matchstr);
    camel_mime_parser_state_t camel_mime_parser_step        (CamelMimeParser *parser,
                                                             gchar **databuffer,
                                                             gsize *datalength);
    void                camel_mime_parser_unstep            (CamelMimeParser *parser);
    void                camel_mime_parser_drop_step         (CamelMimeParser *parser);
    camel_mime_parser_state_t camel_mime_parser_state       (CamelMimeParser *parser);
    void                camel_mime_parser_push_state        (CamelMimeParser *mp,
                                                             camel_mime_parser_state_t newstate,
                                                             const gchar *boundary);
    gint                camel_mime_parser_read              (CamelMimeParser *parser,
                                                             const gchar **databuffer,
                                                             gint len,
                                                             GError **error);
    CamelContentType *  camel_mime_parser_content_type      (CamelMimeParser *parser);
    const gchar *       camel_mime_parser_header            (CamelMimeParser *m,
                                                             const gchar *name,
                                                             gint *offset);
    struct _camel_header_raw * camel_mime_parser_headers_raw
                                                            (CamelMimeParser *m);
    const gchar *       camel_mime_parser_preface           (CamelMimeParser *m);
    const gchar *       camel_mime_parser_postface          (CamelMimeParser *m);
    const gchar *       camel_mime_parser_from_line         (CamelMimeParser *m);
    gint                camel_mime_parser_filter_add        (CamelMimeParser *m,
                                                             CamelMimeFilter *mf);
    void                camel_mime_parser_filter_remove     (CamelMimeParser *m,
                                                             gint id);
    goffset             camel_mime_parser_tell              (CamelMimeParser *parser);
    goffset             camel_mime_parser_seek              (CamelMimeParser *parser,
                                                             goffset offset,
                                                             gint whence);
    goffset             camel_mime_parser_tell_start_headers
                                                            (CamelMimeParser *parser);
    goffset             camel_mime_parser_tell_start_from   (CamelMimeParser *parser);
    goffset             camel_mime_parser_tell_start_boundary
                                                            (CamelMimeParser *parser);

## Object Hierarchy

      GObject
       +----CamelMimeParser

## Description

## Details

### struct CamelMimeParser

    struct CamelMimeParser;

### enum camel_mime_parser_state_t

    typedef enum {
    	CAMEL_MIME_PARSER_STATE_INITIAL,
    	CAMEL_MIME_PARSER_STATE_PRE_FROM,       /* data before a 'From' line */
    	CAMEL_MIME_PARSER_STATE_FROM,           /* got 'From' line */
    	CAMEL_MIME_PARSER_STATE_HEADER,         /* toplevel header */
    	CAMEL_MIME_PARSER_STATE_BODY,           /* scanning body of message */
    	CAMEL_MIME_PARSER_STATE_MULTIPART,      /* got multipart header */
    	CAMEL_MIME_PARSER_STATE_MESSAGE,        /* rfc822 message */

    	CAMEL_MIME_PARSER_STATE_PART,           /* part of a multipart */

    	CAMEL_MIME_PARSER_STATE_END = 8,        /* bit mask for 'end' flags */

    	CAMEL_MIME_PARSER_STATE_EOF = 8,        /* end of file */
    	CAMEL_MIME_PARSER_STATE_PRE_FROM_END,   /* pre from end */
    	CAMEL_MIME_PARSER_STATE_FROM_END,       /* end of whole from bracket */
    	CAMEL_MIME_PARSER_STATE_HEADER_END,     /* dummy value */
    	CAMEL_MIME_PARSER_STATE_BODY_END,       /* end of message */
    	CAMEL_MIME_PARSER_STATE_MULTIPART_END,  /* end of multipart  */
    	CAMEL_MIME_PARSER_STATE_MESSAGE_END     /* end of message */
    } camel_mime_parser_state_t;

`CAMEL_MIME_PARSER_STATE_INITIAL` |
`CAMEL_MIME_PARSER_STATE_PRE_FROM` |
`CAMEL_MIME_PARSER_STATE_FROM` |
`CAMEL_MIME_PARSER_STATE_HEADER` |
`CAMEL_MIME_PARSER_STATE_BODY` |
`CAMEL_MIME_PARSER_STATE_MULTIPART` |
`CAMEL_MIME_PARSER_STATE_MESSAGE` |
`CAMEL_MIME_PARSER_STATE_PART` |
`CAMEL_MIME_PARSER_STATE_END` |
`CAMEL_MIME_PARSER_STATE_EOF` |
`CAMEL_MIME_PARSER_STATE_PRE_FROM_END` |
`CAMEL_MIME_PARSER_STATE_FROM_END` |
`CAMEL_MIME_PARSER_STATE_HEADER_END` |
`CAMEL_MIME_PARSER_STATE_BODY_END` |
`CAMEL_MIME_PARSER_STATE_MULTIPART_END` |
`CAMEL_MIME_PARSER_STATE_MESSAGE_END` |

### camel_mime_parser_new ()

    CamelMimeParser *   camel_mime_parser_new               (void);

Create a new CamelMimeParser object.

Returns : | A new CamelMimeParser widget.

### camel_mime_parser_errno ()

    gint                camel_mime_parser_errno             (CamelMimeParser *parser);

### camel_mime_parser_init_with_fd ()

    gint                camel_mime_parser_init_with_fd      (CamelMimeParser *m,
                                                             gint fd);

Initialise the scanner with an fd. The scanner's offsets will be relative to the current file position of the file descriptor. As a result, seekable descritors should be seeked using the parser seek functions.

`fd` : | A valid file descriptor.
Returns : | Returns -1 on error.

### camel_mime_parser_init_with_stream ()

    gint                camel_mime_parser_init_with_stream  (CamelMimeParser *m,
                                                             CamelStream *stream,
                                                             GError **error);

Initialise the scanner with a source stream. The scanner's offsets will be relative to the current file position of the stream. As a result, seekable streams should only be seeked using the parser seek function.

`error` : | return location for a GError, or `NULL`
Returns : | -1 on error.

### camel_mime_parser_init_with_input_stream ()

    void                camel_mime_parser_init_with_input_stream
                                                            (CamelMimeParser *parser,
                                                             GInputStream *input_stream);

Initialize the scanner with `input_stream`. The scanner's offsets will be relative to the current file position of the stream. As a result, seekable streams should only be seeked using the parser seek function.

`parser` : | a CamelMimeParser
`input_stream` : | a GInputStream

Since 3.12

### camel_mime_parser_init_with_bytes ()

    void                camel_mime_parser_init_with_bytes   (CamelMimeParser *parser,
                                                             GBytes *bytes);

Convenience function creates a GMemoryInputStream from `bytes` and hands it off to `camel_mime_parser_init_with_input_stream()`.

`parser` : | a CamelMimeParser
`bytes` : | a GBytes containing the message content

Since 3.12

### camel_mime_parser_stream ()

    CamelStream *       camel_mime_parser_stream            (CamelMimeParser *parser);

Get the stream, if any, the parser has been initialised with. May be used to setup sub-streams, but should not be read from directly (without saving and restoring the seek position in between).

`parser` : | MIME parser object
Returns : | The stream from `_init_with_stream()`, or NULL if the parser is reading from a file descriptor or is uninitialised.

### camel_mime_parser_scan_from ()

    void                camel_mime_parser_scan_from         (CamelMimeParser *parser,
                                                             gboolean scan_from);

Tell the scanner if it should scan "^From " lines or not.

If the scanner is scanning from lines, two additional states CAMEL_MIME_PARSER_STATE_FROM and CAMEL_MIME_PARSER_STATE_FROM_END will be returned to the caller during parsing.

This may also be preceeded by an optional CAMEL_MIME_PARSER_STATE_PRE_FROM state which contains the scanned data found before the From line is encountered. See also `scan_pre_from()`.

`parser` : | MIME parser object
`scan_from` : | `TRUE` if the scanner should scan From lines.

### camel_mime_parser_scan_pre_from ()

    void                camel_mime_parser_scan_pre_from     (CamelMimeParser *parser,
                                                             gboolean scan_pre_from);

Tell the scanner whether we want to know abou the pre-from data during a scan. If we do, then we may get an additional state CAMEL_MIME_PARSER_STATE_PRE_FROM which returns the specified data.

`parser` : | MIME parser object
`scan_pre_from` : | `TRUE` if we want to get pre-from data.

### camel_mime_parser_set_header_regex ()

    gint                camel_mime_parser_set_header_regex  (CamelMimeParser *parser,
                                                             gchar *matchstr);

### camel_mime_parser_step ()

    camel_mime_parser_state_t camel_mime_parser_step        (CamelMimeParser *parser,
                                                             gchar **databuffer,
                                                             gsize *datalength);

Parse the next part of the MIME message. If `_unstep()` has been called, then continue to return the same state for that many calls.

If the step is CAMEL_MIME_PARSER_STATE_BODY then the databuffer and datalength pointers will be setup to point to the internal data buffer of the scanner and may be processed as required. Any filters will have already been applied to this data.

Refer to the state diagram elsewhere for a full listing of the states an application is gauranteed to get from the scanner.

`parser` : | MIME parser object
`databuffer` : | Pointer to accept a pointer to the data associated with this step (if any). May be `NULL`, in which case datalength is also ingored.
`datalength` : | Pointer to accept a pointer to the data length associated with this step (if any).
Returns : | The current new state of the parser is returned.

### camel_mime_parser_unstep ()

    void                camel_mime_parser_unstep            (CamelMimeParser *parser);

Cause the last step operation to repeat itself. If this is called repeated times, then the same step will be repeated that many times.

Note that it is not possible to scan back using this function, only to have a way of peeking the next state.

`parser` : | MIME parser object

### camel_mime_parser_drop_step ()

    void                camel_mime_parser_drop_step         (CamelMimeParser *parser);

Drop the last step call. This should only be used in conjunction with seeking of the stream as the stream may be in an undefined state relative to the state of the parser.

Use this call with care.

`parser` : | MIME parser object

### camel_mime_parser_state ()

    camel_mime_parser_state_t camel_mime_parser_state       (CamelMimeParser *parser);

Get the current parser state.

`parser` : | MIME parser object
Returns : | The current parser state.

### camel_mime_parser_push_state ()

    void                camel_mime_parser_push_state        (CamelMimeParser *mp,
                                                             camel_mime_parser_state_t newstate,
                                                             const gchar *boundary);

Pre-load a new parser state. Used to post-parse multipart content without headers.

`mp` : | MIME parser object
`newstate` : | New state
`boundary` : | Boundary marker for state.

### camel_mime_parser_read ()

    gint                camel_mime_parser_read              (CamelMimeParser *parser,
                                                             const gchar **databuffer,
                                                             gint len,
                                                             GError **error);

Read at most `len` bytes from the internal mime parser buffer.

Returns the address of the internal buffer in `databuffer`, and the length of useful data.

`len` may be specified as INT_MAX, in which case you will get the full remainder of the buffer at each call.

Note that no parsing of the data read through this function occurs, so no state changes occur, but the seek position is updated appropriately.

`parser` : | MIME parser object
`error` : | return location for a GError, or `NULL`
Returns : | The number of bytes available, or -1 on error.

### camel_mime_parser_content_type ()

    CamelContentType *  camel_mime_parser_content_type      (CamelMimeParser *parser);

Get the content type defined in the current part.

`parser` : | MIME parser object
Returns : | A content_type structure, or NULL if there is no content-type defined for this part of state of the parser.

### camel_mime_parser_header ()

    const gchar *       camel_mime_parser_header            (CamelMimeParser *m,
                                                             const gchar *name,
                                                             gint *offset);

Lookup a header by name.

`name` : | Name of header.
`offset` : | Pointer that can receive the offset of the header in the stream from the start of parsing.
Returns : | The header value, or NULL if the header is not defined.

### camel_mime_parser_headers_raw ()

    struct _camel_header_raw * camel_mime_parser_headers_raw
                                                            (CamelMimeParser *m);

Get the list of the raw headers which are defined for the current state of the parser. These headers are valid until the next call to `parser_step()`, or `parser_drop_step()`.

Returns : | The raw headers, or NULL if there are no headers defined for the current part or state. These are READ ONLY.

Since 2.22

### camel_mime_parser_preface ()

    const gchar *       camel_mime_parser_preface           (CamelMimeParser *m);

Retrieve the preface text for the current multipart. Can only be used when the state is CAMEL_MIME_PARSER_STATE_MULTIPART_END.

Returns : | The preface text, or NULL if there wasn't any.

Since 2.22

### camel_mime_parser_postface ()

    const gchar *       camel_mime_parser_postface          (CamelMimeParser *m);

Retrieve the postface text for the current multipart. Only returns valid data when the current state if CAMEL_MIME_PARSER_STATE_MULTIPART_END.

Returns : | The postface text, or NULL if there wasn't any.

Since 2.22

### camel_mime_parser_from_line ()

    const gchar *       camel_mime_parser_from_line         (CamelMimeParser *m);

Get the last scanned "From " line, from a recently scanned from. This should only be called in the CAMEL_MIME_PARSER_STATE_FROM state. The from line will include the closing \n found (if there was one).

The return value will remain valid while in the CAMEL_MIME_PARSER_STATE_FROM state, or any deeper state.

Returns : | The From line, or NULL if called out of context.

Since 2.22

### camel_mime_parser_filter_add ()

    gint                camel_mime_parser_filter_add        (CamelMimeParser *m,
                                                             CamelMimeFilter *mf);

Add a filter that will be applied to any body content before it is passed to the caller. Filters may be pipelined to perform multi-pass operations on the content, and are applied in the order they were added.

Note that filters are only applied to the body content of messages, and once a filter has been set, all content returned by a `filter_step()` with a state of CAMEL_MIME_PARSER_STATE_BODY will have passed through the filter.

Returns : | An id that may be passed to `filter_remove()` to remove the filter, or -1 if the operation failed.

Since 2.22

### camel_mime_parser_filter_remove ()

    void                camel_mime_parser_filter_remove     (CamelMimeParser *m,
                                                             gint id);

Remove a processing filter from the pipeline. There is no restriction on the order the filters can be removed.

Since 2.22

### camel_mime_parser_tell ()

    goffset             camel_mime_parser_tell              (CamelMimeParser *parser);

Return the current scanning offset. The meaning of this value will depend on the current state of the parser.

An incomplete listing of the states:

CAMEL_MIME_PARSER_STATE_INITIAL, The start of the current message. CAMEL_MIME_PARSER_STATE_HEADER, CAMEL_MIME_PARSER_STATE_MESSAGE, CAMEL_MIME_PARSER_STATE_MULTIPART, the character position immediately after the end of the header. CAMEL_MIME_PARSER_STATE_BODY, Position within the message of the start of the current data block. CAMEL_MIME_PARSER_STATE_*_END, The position of the character starting the next section of the scan (the last position + 1 of the respective current state).

`parser` : | MIME parser object
Returns : | See above.

Since 2.22

### camel_mime_parser_seek ()

    goffset             camel_mime_parser_seek              (CamelMimeParser *parser,
                                                             goffset offset,
                                                             gint whence);

Reset the source position to a known value.

Note that if the source stream/descriptor was not positioned at 0 to begin with, and an absolute seek is specified (whence != SEEK_CUR), then the seek position may not match the desired seek position.

`parser` : | MIME parser object
`offset` : | Number of bytes to offset the seek by.
`whence` : | SEEK_SET, SEEK_CUR, SEEK_END
Returns : | The new seek offset, or -1 on an error (for example, trying to seek on a non-seekable stream or file descriptor).

Since 2.22

### camel_mime_parser_tell_start_headers ()

    goffset             camel_mime_parser_tell_start_headers
                                                            (CamelMimeParser *parser);

Find out the position within the file of where the headers started, this is cached by the parser at the time.

`parser` : | MIME parser object
Returns : | The header start position, or -1 if no headers were scanned in the current state.

Since 2.22

### camel_mime_parser_tell_start_from ()

    goffset             camel_mime_parser_tell_start_from   (CamelMimeParser *parser);

If the parser is scanning From lines, then this returns the position of the start of the From line.

`parser` : | MIME parser object
Returns : | The start of the from line, or -1 if there was no From line, or From lines are not being scanned.

Since 2.22

### camel_mime_parser_tell_start_boundary ()

    goffset             camel_mime_parser_tell_start_boundary
                                                            (CamelMimeParser *parser);

When parsing a multipart, this returns the start of the last boundary.

`parser` : | MIME parser object
Returns : | The start of the boundary, or -1 if there was no boundary encountered yet.

Since 2.22