Click here to Skip to main content
15,867,686 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 371.4K   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

 
QuestionReading the To/From Properties Pin
Terence Agius5-Apr-13 7:35
Terence Agius5-Apr-13 7:35 
GeneralNeed Help - Can't get MimeSniffer.Load(streamObject) to work Pin
Eveng Thao16-Sep-10 16:30
Eveng Thao16-Sep-10 16:30 
GeneralOpen an .eml, change the from and save Pin
hombrewolf2-Feb-10 8:02
hombrewolf2-Feb-10 8:02 
Generalfaile decoder.CreateInstance(__uuidof(MimeDecoder)) Pin
toby198323-Jan-10 5:31
toby198323-Jan-10 5:31 
QuestionCan not read body text Pin
sandeepkgsmarty21-Jan-09 17:50
sandeepkgsmarty21-Jan-09 17:50 
GeneralBe aware ! MimeSniffer.dll is a spyware ! Pin
ntt6825-Oct-07 23:43
ntt6825-Oct-07 23:43 
GeneralRe: Be aware ! MimeSniffer.dll is a spyware ! Pin
prakash gajera5-Apr-09 19:49
prakash gajera5-Apr-09 19:49 
QuestionCan someone please have a quick look at this? Pin
ieaarva12-Sep-07 1:13
ieaarva12-Sep-07 1:13 
GeneralI'm glad i found you/this Pin
vbxbert9-Jan-07 6:28
vbxbert9-Jan-07 6:28 
Generalerrors building MimeSniffer on vs 2005 Pin
papaflo6-Apr-06 14:33
papaflo6-Apr-06 14:33 
AnswerRe: errors building MimeSniffer on vs 2005 Pin
N5ARW28-Feb-07 8:18
N5ARW28-Feb-07 8:18 
GeneralMIME to HTML conversion problem if MIME buffer's Tag Starts with <DIV> , <P> or <UL> Pin
chandan kumar19-Aug-05 2:11
chandan kumar19-Aug-05 2:11 
GeneralUsing Streams with C# Pin
iam.TJ28-Jul-05 4:56
iam.TJ28-Jul-05 4:56 
GeneralProblem with .txt attachments Pin
Dav3R0ck22-Apr-05 11:49
Dav3R0ck22-Apr-05 11:49 
GeneralRe: Problem with .txt attachments Pin
sandeepkgsmarty23-Jan-09 3:27
sandeepkgsmarty23-Jan-09 3:27 
QuestionIs this entry still beign maintained? Pin
ShadowCat2117-Nov-04 11:51
ShadowCat2117-Nov-04 11:51 
GeneralEnterprise liscence Pin
bobmorton28-Jun-04 22:21
bobmorton28-Jun-04 22:21 
General100% CPU Load and no result when decoding messages Pin
C.Bendt22-Jun-04 10:18
C.Bendt22-Jun-04 10:18 
GeneralRe: 100% CPU Load and no result when decoding messages Pin
megamoose7-Oct-07 1:03
megamoose7-Oct-07 1:03 
GeneralDec.Body gave Type mismatch Pin
Yogesh Jangam25-May-04 23:05
Yogesh Jangam25-May-04 23:05 
GeneralRe: Dec.Body gave Type mismatch Pin
Yogesh Jangam7-Jun-04 21:16
Yogesh Jangam7-Jun-04 21:16 
GeneralSome eml decode failed Pin
z_j4-May-04 23:45
z_j4-May-04 23:45 
GeneralUUE Attachements Pin
De O Bolonn3-May-04 18:17
De O Bolonn3-May-04 18:17 
Generalprogramming challenge Pin
Anonymous8-Mar-04 1:47
Anonymous8-Mar-04 1:47 
GeneralCannot get text part of multi part body Pin
stempsoft7-Feb-04 16:09
stempsoft7-Feb-04 16:09 

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.