Click here to Skip to main content
15,889,992 members
Articles / Desktop Programming / ATL
Article

En/Decode MIME-Content with MimeSniffer

Rate me:
Please Sign up or sign in to vote.
4.88/5 (26 votes)
2 Dec 20022 min read 375.2K   7K   74   164
RFC-compliant Mime-En/Decoder

Introduction

The Code Project offers many helper-classes for sending (SMTP) and retrieving (POP3) internet mail. But these modules won't help you any further because the content is still raw and must be cooked. The content is in MIME format wich is documented in RFC2045, RFC1521 and RFC822. If you take a look at these RFCs you'll know why (free) implementations are rare.

Technical Details

The MimeSniffer is a VC++ ATL project. The parser has been realized with lex and yacc (flex and bison). It comes with a neat COM object (without a GUI), that implements IPersistStream. Although the MimeSniffer includes a stream-helper for files (for demonstration purposes), the implementation of the stream-object is left up to you (e.g. socket). The COM object provides a dispatch-interface so that VB developers could come along.

Usage

First of all, don't forget to register the COM server MimeSniffer.dll - which comes with both demos - using regsvr32.exe. You may create, read or modify MIME content. The interface is very easy and I will only provide VBS code samples in this article. Download the demo project for a VC++ sample.

Encoding

Here's a sample of the minimum amount of code (VBScript) that you must use to create an email message. It's very straight forward.

VBScript
rem -- Altough the Object's name is "Decoder", it's able to "encode"<BR>rem -- mime content
set Dec	= CreateObject("MimeSniffer.Decoder")

rem -- supply minimal information
Dec.From	= "me@home.com"
Dec.To		= "friend@server.com"
Dec.Subject	= "Lunch"
Dec.Body	= "Hi! Let's do lunch....."

rem -- "Send" the email to a stream
Dec.SaveToFile "mail1.txt"

If you take a look at the file mail1.txt afterward, you'll see that the COM object handles char-encoding properly:

Subject: =?iso-8859-1?Q?Lunch?=

The interface has "raw" properties to access this and similar fields without being en/decoded. E.g. use the property SubjectRaw.

Most mail messages today are multipart mail messages. E.g. Outlook generally generates mail messages with a multipart body even if there's only one part. The next sample shows how to create an multipart email with two parts - a text and a file as an attachment.

VBScript
set Dec	= CreateObject("MimeSniffer.Decoder")

rem -- supply head information
Dec.From	= "me@home.com"
Dec.To		= "friend@server.com"
Dec.Subject	= "Test"

rem -- get root body object...
set Body	= Dec.Body

rem -- ...wich will consist of multiple parts
Body.MajorContentType	= "multipart"
Body.MinorContentType	= "mixed"

rem -- insert a new body object
set TextBody = Body.AddNew()

rem -- set header information for this part
TextBody.MajorContentType	= "text"
TextBody.MinorContentType	= "plain"
TextBody.Encoding		= "quoted-printable"

rem -- set the content
TextBody.Value = "This is the text part!"

rem -- insert a new body object
set PicBody = Body.AddNew()

rem -- set header information for this part
PicBody.MajorContentType	= "image"
PicBody.MinorContentType	= "jpeg"
PicBody.Encoding		= "Base64"

rem -- import the content
PicBody.ImportFromFile "duke.jpg", True

rem -- declare the second part as an attachment
PicBody.FileName = "duke.jpg"

rem -- "Send" the email to a stream
Dec.SaveToFile "mail2.txt"

Decoding

Decoding is even easier than encoding. All you need to do is to create a stream object and to IPersistStream::Load the MimeSniffer persistent from this stream. Then access/modify the objects and re-send the content. So MimeSniffer can act like a filter. The following sample uses the previously created file mail2.txt.

VBScript
set Dec	= CreateObject("MimeSniffer.Decoder")

rem -- IPersistStream::Load the content
Dec.LoadFromFile "mail2.txt"

rem -- throw the subject
MsgBox "Subject is: " & Dec.Subject

rem -- modify the subject
Dec.Subject = "Extended " & Dec.Subject

rem -- get root body object...
set Body	= Dec.Body

rem -- get the text part, wich is the first part
set TextBody = Body(0)

rem -- throw the content
MsgBox "Body-Text is: " & TextBody.Value

rem -- modify the text part
TextBody.Value = TextBody.Value & Chr(13) & Chr(10) & "Nice, isn't it?"

rem -- get the pic part, wich is the second part
set PicBody = Body(1)

rem -- extract the content to a stream
PicBody.ExportAsFile "copy of " & PicBody.FileName

rem -- "Send" the modified email to a stream
Dec.SaveToFile "mail3.txt"

There are many more properties which are very straight forward I think. Questions and comments are welcome.

Update History

  • 12/02/2002 - Corrected the "month-enum" bug in yystype.cpp
  • 12/02/2002 - Enhanced speed for large emails by modifications in Stream-implementation
  • 02/03/2002 - Compiles with VS .NET
  • 02/03/2002 - Removed a bug, where nested Multiparts got wrong boundary-identifiers

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralRe: Decode MIME Pin
Randolph Duke8-Sep-03 23:54
Randolph Duke8-Sep-03 23:54 
GeneralLoad string instead of file Pin
calvinlai20-Aug-03 23:51
calvinlai20-Aug-03 23:51 
GeneralRe: Load string instead of file Pin
Randolph Duke21-Aug-03 1:14
Randolph Duke21-Aug-03 1:14 
GeneralRe: Load string instead of file Pin
calvinlai21-Aug-03 1:47
calvinlai21-Aug-03 1:47 
GeneralRe: Load string instead of file Pin
LukeV2-Sep-03 7:05
LukeV2-Sep-03 7:05 
GeneralRe: Load string instead of file Pin
virabadrasana17-Nov-03 21:02
virabadrasana17-Nov-03 21:02 
Questionhow to create such project step in step? Pin
8-Aug-03 23:53
suss8-Aug-03 23:53 
GeneralNo body Pin
simorf5-Aug-03 23:59
simorf5-Aug-03 23:59 
Using ASP i am able to download all emails and their attachments to my machine(using ASPOP3). Some of the attachments are themselves emails. However when i read these emails (using the Filetextstream object) the text has additonal characters in it. I think this is to with the charset type. If i send these emails straight to aspPOP3 instead of as an attachment to another email then they are able to be read by aspop3 with no problems. It appears the ASPOP3 has the capability of correctly identifying and converting the charset.

I tried your MimeSniffer in the hope of reading these saved email. while it does parse the subject, no body is returned. I would love to email you the file I am trying to parse so that you could see for yourself

Lemme Know

Thanks for your time.. and the component

Regards

Simon orford

GeneralQuestion Pin
nonahelmi30-Jul-03 15:56
nonahelmi30-Jul-03 15:56 
Generalstandalone (no COM) Pin
rlnd14-Jul-03 5:22
rlnd14-Jul-03 5:22 
GeneralISO8859-1 issue Pin
shugami10-Jul-03 3:58
shugami10-Jul-03 3:58 
GeneralDecoding from saved POP3 Pin
pc429-Jun-03 0:30
pc429-Jun-03 0:30 
GeneralRe: Decoding from saved POP3 Pin
Randolph Duke29-Jun-03 23:25
Randolph Duke29-Jun-03 23:25 
GeneralGrammar Pin
bickel25-Jun-03 8:31
bickel25-Jun-03 8:31 
GeneralGetSubject hangs Pin
Vol18-Jun-03 23:02
Vol18-Jun-03 23:02 
GeneralRe: GetSubject hangs Pin
salvaterra21-Apr-04 4:27
salvaterra21-Apr-04 4:27 
GeneralMinor and Major Content Types Pin
Unsubscribed28-May-03 3:53
Unsubscribed28-May-03 3:53 
GeneralRe: Minor and Major Content Types Pin
Randolph Duke2-Jun-03 0:23
Randolph Duke2-Jun-03 0:23 
QuestionBug with Sender? Pin
HippoTas27-May-03 0:34
HippoTas27-May-03 0:34 
Generalgetting the size of attachment Pin
Anonymous24-May-03 4:53
Anonymous24-May-03 4:53 
GeneralWrong Decoding Pin
HippoTas13-May-03 5:22
HippoTas13-May-03 5:22 
GeneralWindows CE Pin
Member 3495286-May-03 5:43
Member 3495286-May-03 5:43 
GeneralNot able to extract attachment for few mail client Pin
pralaypati1-May-03 20:28
pralaypati1-May-03 20:28 
Questionworks with C#??? Pin
fernara22-Apr-03 17:51
fernara22-Apr-03 17:51 
GeneralCommercial Usage Pin
boots14-Apr-03 22:17
boots14-Apr-03 22:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.