Back to index

lightning-sunbird  0.9+nobinonly
mimei.h
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #ifndef _MIMEI_H_
00039 #define _MIMEI_H_
00040 
00041 /*
00042   This module, libmime, implements a general-purpose MIME parser.
00043   One of the methods provided by this parser is the ability to emit
00044   an HTML representation of it.
00045 
00046   All Mozilla-specific code is (and should remain) isolated in the
00047   file mimemoz.c.  Generally, if the code involves images, netlib
00048   streams it should be in mimemoz.c instead of in the main body of 
00049   the MIME parser.
00050 
00051   The parser is object-oriented and fully buzzword-compliant.
00052   There is a class for each MIME type, and each class is responsible
00053   for parsing itself, and/or handing the input data off to one of its
00054   child objects.
00055 
00056   The class hierarchy is:
00057 
00058      MimeObject (abstract)
00059       |
00060       +--- MimeContainer (abstract)
00061       |     |
00062       |     +--- MimeMultipart (abstract)
00063       |     |     |
00064       |     |     +--- MimeMultipartMixed
00065       |     |     |
00066       |     |     +--- MimeMultipartDigest
00067       |     |     |
00068       |     |     +--- MimeMultipartParallel
00069       |     |     |
00070       |     |     +--- MimeMultipartAlternative
00071       |     |     |
00072       |     |     +--- MimeMultipartRelated
00073       |     |     |
00074       |     |     +--- MimeMultipartAppleDouble
00075       |     |     |
00076       |     |     +--- MimeSunAttachment
00077       |     |     |
00078       |     |     \--- MimeMultipartSigned (abstract)
00079       |     |          |
00080       |     |          \--- MimeMultipartSignedCMS
00081       |     |
00082       |     +--- MimeEncrypted (abstract)
00083       |     |     |
00084       |     |     \--- MimeEncryptedPKCS7
00085       |     |
00086       |     +--- MimeXlateed (abstract)
00087       |     |     |
00088       |     |     \--- MimeXlateed
00089       |     |
00090       |     +--- MimeMessage
00091       |     |
00092       |     \--- MimeUntypedText
00093       |
00094       +--- MimeLeaf (abstract)
00095       |     |
00096       |     +--- MimeInlineText (abstract)
00097       |     |     |
00098       |     |     +--- MimeInlineTextPlain
00099       |     |     |     |
00100       |     |     |     \--- MimeInlineTextHTMLAsPlaintext
00101       |     |     |
00102       |     |     +--- MimeInlineTextPlainFlowed
00103       |     |     |
00104       |     |     +--- MimeInlineTextHTML
00105       |     |     |     |
00106       |     |     |     \--- MimeInlineTextHTMLSanitized
00107       |     |     |
00108       |     |     +--- MimeInlineTextRichtext
00109       |     |     |     |
00110       |     |     |     \--- MimeInlineTextEnriched
00111       |     |   |
00112       |     |   +--- MimeInlineTextVCard
00113       |     |
00114       |     +--- MimeInlineImage
00115       |     |
00116       |     \--- MimeExternalObject
00117       |
00118       \--- MimeExternalBody
00119 
00120 
00121   =========================================================================
00122   The definition of these classes is somewhat idiosyncratic, since I defined
00123   my own small object system, instead of giving the C++ virus another foothold.
00124   (I would have liked to have written this in Java, but our runtime isn't
00125   quite ready for prime time yet.)
00126 
00127   There is one header file and one source file for each class (for example,
00128   the MimeInlineText class is defined in "mimetext.h" and "mimetext.c".)
00129   Each header file follows the following boiler-plate form:
00130 
00131   TYPEDEFS: these come first to avoid circular dependencies.
00132 
00133       typedef struct FoobarClass FoobarClass;
00134       typedef struct Foobar      Foobar;
00135 
00136   CLASS DECLARATION:
00137   Theis structure defines the callback routines and other per-class data
00138   of the class defined in this module.
00139 
00140       struct FoobarClass {
00141         ParentClass superclass;
00142         ...any callbacks or class-variables...
00143       };
00144 
00145   CLASS DEFINITION:
00146   This variable holds an instance of the one-and-only class record; the
00147   various instances of this class point to this object.  (One interrogates
00148   the type of an instance by comparing the value of its class pointer with
00149   the address of this variable.)
00150 
00151       extern FoobarClass foobarClass;
00152 
00153   INSTANCE DECLARATION:
00154   Theis structure defines the per-instance data of an object, and a pointer
00155   to the corresponding class record.
00156 
00157       struct Foobar {
00158         Parent parent;
00159         ...any instance variables...
00160       };
00161 
00162   Then, in the corresponding .c file, the following structure is used:
00163 
00164   CLASS DEFINITION:
00165   First we pull in the appropriate include file (which includes all necessary
00166   include files for the parent classes) and then we define the class object
00167   using the MimeDefClass macro:
00168 
00169       #include "foobar.h"
00170       #define MIME_SUPERCLASS parentlClass
00171       MimeDefClass(Foobar, FoobarClass, foobarClass, &MIME_SUPERCLASS);
00172 
00173   The definition of MIME_SUPERCLASS is just to move most of the knowlege of the
00174   exact class hierarchy up to the file's header, instead of it being scattered
00175   through the various methods; see below.
00176 
00177   METHOD DECLARATIONS:
00178   We will be putting function pointers into the class object, so we declare
00179   them here.  They can generally all be static, since nobody outside of this
00180   file needs to reference them by name; all references to these routines should
00181   be through the class object.
00182 
00183       extern int FoobarMethod(Foobar *);
00184       ...etc...
00185 
00186   CLASS INITIALIZATION FUNCTION:
00187   The MimeDefClass macro expects us to define a function which will finish up
00188   any initialization of the class object that needs to happen before the first
00189   time it is instantiated.  Its name must be of the form "<class>Initialize",
00190   and it should initialize the various method slots in the class as
00191   appropriate.  Any methods or class variables which this class does not wish
00192   to override will be automatically inherited from the parent class (by virtue
00193   of its class-initialization function having been run first.)  Each class
00194   object will only be initialized once.
00195 
00196       static int
00197       FoobarClassInitialize(FoobarClass *class)
00198       {
00199         clazz->method = FoobarMethod.
00200         ...etc...
00201       }
00202 
00203   METHOD DEFINITIONS:
00204   Next come the definitions of the methods we referred to in the class-init
00205   function.  The way to access earlier methods (methods defined on the
00206   superclass) is to simply extract them from the superclass's object.
00207   But note that you CANNOT get at methods by indirecting through
00208   object->clazz->superclass: that will only work to one level, and will
00209   go into a loop if some subclass tries to continue on this method.
00210 
00211   The easiest way to do this is to make use of the MIME_SUPERCLASS macro that
00212   was defined at the top of the file, as shown below.  The alternative to that
00213   involves typing the literal name of the direct superclass of the class
00214   defined in this file, which will be a maintenance headache if the class
00215   hierarchy changes.  If you use the MIME_SUPERCLASS idiom, then a textual
00216   change is required in only one place if this class's superclass changes.
00217 
00218       static void
00219       Foobar_finalize (MimeObject *object)
00220       {
00221         ((MimeObjectClass*)&MIME_SUPERCLASS)->finalize(object);  //  RIGHT
00222         parentClass.whatnot.object.finalize(object);             //  (works...)
00223         object->clazz->superclass->finalize(object);             //  WRONG!!
00224       }
00225 
00226   If you write a libmime content type handler, libmime might create several
00227   instances of your class at once and call e.g. the same finalize code for
00228   3 different objects in a row.
00229  */
00230 
00231 #include "mimehdrs.h"
00232 #include "nsVoidArray.h"
00233 
00234 typedef struct MimeObject      MimeObject;
00235 typedef struct MimeObjectClass MimeObjectClass;
00236 
00237 #ifdef ENABLE_SMIME
00238 class nsICMSMessage;
00239 #endif // ENABLE_SMIME
00240 
00241 /* (I don't pretend to understand this.) */
00242 #define cpp_stringify_noop_helper(x)#x
00243 #define cpp_stringify(x) cpp_stringify_noop_helper(x)
00244 
00245 
00246 /* Macro used for setting up class definitions.
00247  */
00248 #define MimeDefClass(ITYPE,CTYPE,CVAR,CSUPER) \
00249  static int CTYPE##Initialize(CTYPE *); \
00250  CTYPE CVAR = { cpp_stringify(ITYPE), sizeof(ITYPE), \
00251                             (MimeObjectClass *) CSUPER, \
00252                             (int (*) (MimeObjectClass *)) CTYPE##Initialize, 0, }
00253 
00254 
00255 /* Creates a new (subclass of) MimeObject of the given class, with the
00256    given headers (which are copied.)
00257  */
00258 extern MimeObject *mime_new (MimeObjectClass *clazz, MimeHeaders *hdrs,
00259                                                   const char *override_content_type);
00260 
00261 
00262 /* Destroys a MimeObject (or subclass) and all data associated with it.
00263  */
00264 extern "C" void mime_free (MimeObject *object);
00265 
00266 /* Given a content-type string, finds and returns an appropriate subclass
00267    of MimeObject.  A class object is returned.  If `exact_match_p' is true,
00268    then only fully-known types will be returned; that is, if it is true,
00269    then "text/x-unknown" will return MimeInlineTextPlainType, but if it is
00270    false, it will return NULL.
00271  */
00272 extern MimeObjectClass *mime_find_class (const char *content_type,
00273                                                                        MimeHeaders *hdrs,
00274                                                                        MimeDisplayOptions *opts,
00275                                                                        PRBool exact_match_p);
00276 
00277 /* Given a content-type string, creates and returns an appropriate subclass
00278    of MimeObject.  The headers (from which the content-type was presumably
00279    extracted) are copied.
00280  */
00281 extern MimeObject *mime_create (const char *content_type, MimeHeaders *hdrs,
00282                                                         MimeDisplayOptions *opts);
00283 
00284 
00285 /* Querying the type hierarchy */
00286 extern PRBool mime_subclass_p(MimeObjectClass *child,
00287                                                     MimeObjectClass *parent);
00288 extern PRBool mime_typep(MimeObject *obj, MimeObjectClass *clazz);
00289 
00290 /* Returns a string describing the location of the part (like "2.5.3").
00291    This is not a full URL, just a part-number.
00292  */
00293 extern char *mime_part_address(MimeObject *obj);
00294 
00295 /* Returns a string describing the location of the *IMAP* part (like "2.5.3").
00296    This is not a full URL, just a part-number.
00297    This part is explicitly passed in the X-Mozilla-IMAP-Part header.
00298    Return value must be freed by the caller.
00299  */
00300 extern char *mime_imap_part_address(MimeObject *obj);
00301 
00302 extern char *mime_external_attachment_url(MimeObject *obj);
00303 
00304 /* Puts a part-number into a URL.  If append_p is true, then the part number
00305    is appended to any existing part-number already in that URL; otherwise,
00306    it replaces it.
00307  */
00308 extern char *mime_set_url_part(const char *url, const char *part, PRBool append_p);
00309 
00310 /*
00311   cut the part of url for display a attachment as a email.
00312 */
00313 extern char *mime_get_base_url(const char *url);
00314 
00315 /* Puts an *IMAP* part-number into a URL.
00316  */
00317 extern char *mime_set_url_imap_part(const char *url, const char *part, const char *libmimepart);
00318 
00319 
00320 /* Given a part ID, looks through the MimeObject tree for a sub-part whose ID
00321    number matches, and returns the MimeObject (else NULL.)
00322    (part is not a URL -- it's of the form "1.3.5".)
00323  */
00324 extern MimeObject *mime_address_to_part(const char *part, MimeObject *obj);
00325 
00326 
00327 /* Given a part ID, looks through the MimeObject tree for a sub-part whose ID
00328    number matches; if one is found, returns the Content-Name of that part.
00329    Else returns NULL.  (part is not a URL -- it's of the form "1.3.5".)
00330  */
00331 extern char *mime_find_suggested_name_of_part(const char *part,
00332                                                                                MimeObject *obj);
00333 
00334 /* Given a part ID, looks through the MimeObject tree for a sub-part whose ID
00335    number matches; if one is found, returns the Content-Name of that part.
00336    Else returns NULL.  (part is not a URL -- it's of the form "1.3.5".)
00337  */
00338 extern char *mime_find_content_type_of_part(const char *part, MimeObject *obj);
00339 
00340 /* Parse the various "?" options off the URL and into the options struct.
00341  */
00342 extern int mime_parse_url_options(const char *url, MimeDisplayOptions *);
00343 
00344 #ifdef ENABLE_SMIME
00345 
00346 /* Asks whether the given object is one of the cryptographically signed
00347    or encrypted objects that we know about.  (MimeMessageClass uses this
00348    to decide if the headers need to be presented differently.)
00349  */
00350 extern PRBool mime_crypto_object_p(MimeHeaders *, PRBool clearsigned_counts);
00351 
00352 /* Tells whether the given MimeObject is a message which has been encrypted
00353    or signed.  (Helper for MIME_GetMessageCryptoState()). 
00354  */
00355 extern void mime_get_crypto_state (MimeObject *obj,
00356                                                            PRBool *signed_p, PRBool *encrypted_p,
00357                                                            PRBool *signed_ok, PRBool *encrypted_ok);
00358 
00359 
00360 /* Whether the given object has written out the HTML version of its headers
00361    in such a way that it will have a "crypto stamp" next to the headers.  If
00362    this is true, then the child must write out its HTML slightly differently
00363    to take this into account...
00364  */
00365 extern PRBool mime_crypto_stamped_p(MimeObject *obj);
00366 
00367 /* How the crypto code tells the MimeMessage object what the crypto stamp
00368    on it says. */
00369 extern void mime_set_crypto_stamp(MimeObject *obj,
00370                                                           PRBool signed_p, PRBool encrypted_p);
00371 #endif // ENABLE_SMIME
00372 
00373 class MimeParseStateObject {
00374 public:
00375 
00376   MimeParseStateObject() 
00377       {root = 0; separator_queued_p = PR_FALSE; separator_suppressed_p = PR_FALSE;
00378         first_part_written_p = PR_FALSE; post_header_html_run_p = PR_FALSE; first_data_written_p = PR_FALSE; 
00379         decrypted_p = PR_FALSE; strippingPart = PR_FALSE;
00380       }
00381   MimeObject *root;                       /* The outermost parser object. */
00382 
00383   PRBool separator_queued_p;       /* Whether a separator should be written out
00384                                                            before the next text is written (this lets
00385                                                            us write separators lazily, so that one
00386                                                            doesn't appear at the end, and so that more
00387                                                            than one don't appear in a row.) */
00388 
00389   PRBool separator_suppressed_p; /* Whether the currently-queued separator
00390                                                            should not be printed; this is a kludge to
00391                                                            prevent seps from being printed just after
00392                                                            a header block... */
00393 
00394   PRBool first_part_written_p;     /* State used for the `Show Attachments As
00395                                                            Links' kludge. */
00396 
00397   PRBool post_header_html_run_p; /* Whether we've run the
00398                                                                 options->generate_post_header_html_fn */
00399 
00400   PRBool first_data_written_p;     /* State used for Mozilla lazy-stream-
00401                                                            creation evilness. */
00402 
00403   PRBool decrypted_p; /* If options->dexlate_p is true, then this
00404                         will be set to indicate whether any
00405                         dexlateion did in fact occur.
00406                       */
00407   nsCStringArray partsToStrip;      /* if we're stripping parts, what parts to strip */
00408   nsCStringArray detachToFiles;      /* if we're detaching parts, where each part was detached to */
00409   PRBool strippingPart;
00410   nsCString detachedFilePath;       /* if we've detached this part, filepath of detached part */
00411 };
00412 
00413 
00414 
00415 /* Some output-generation utility functions...
00416  */
00417 extern int MimeObject_output_init(MimeObject *obj, const char *content_type);
00418 
00419 /* The `user_visible_p' argument says whether the output that has just been
00420    written will cause characters or images to show up on the screen, that
00421    is, it should be PR_FALSE if the stuff being written is merely structural
00422    HTML or whitespace ("<P>", "</TABLE>", etc.)  This information is used
00423    when making the decision of whether a separating <HR> is needed.
00424  */
00425 extern int MimeObject_write(MimeObject *, const char *data, PRInt32 length,
00426                                                  PRBool user_visible_p);
00427 extern int MimeOptions_write(MimeDisplayOptions *,
00428                                                   const char *data, PRInt32 length,
00429                                                   PRBool user_visible_p);
00430 
00431 /* Writes out the right kind of HR (or rather, queues it for writing.) */
00432 extern int MimeObject_write_separator(MimeObject *);
00433 
00434 extern PRBool MimeObjectChildIsMessageBody(MimeObject *obj,
00435                                                                              PRBool *isAlterOrRelated);
00436 
00437 /* This is the data tagged to contexts and the declaration needs to be
00438    in a header file since more than mimemoz.c needs to see it now...
00439    */
00440 #ifdef HAVE_MIME_DATA_SLOT
00441 # define LOCK_LAST_CACHED_MESSAGE
00442 #endif
00443 
00444 struct MimeDisplayData {            /* This struct is what we hang off of
00445                                        (context)->mime_data, to remember info
00446                                        about the last MIME object we've
00447                                        parsed and displayed.  See
00448                                        MimeGuessURLContentName() below.
00449                                      */
00450   MimeObject *last_parsed_object;
00451   char *last_parsed_url;
00452 
00453 #ifdef LOCK_LAST_CACHED_MESSAGE
00454   char *previous_locked_url;
00455 #endif /* LOCK_LAST_CACHED_MESSAGE */
00456 };
00457 
00458 #endif /* _MIMEI_H_ */