Back to index

lightning-sunbird  0.9+nobinonly
mimeleaf.cpp
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 #include "modmimee.h"
00039 #include "mimeleaf.h"
00040 #include "nsMimeTypes.h"
00041 #include "prmem.h"
00042 #include "plstr.h"
00043 #include "prlog.h"
00044 #include "nsMimeStringResources.h"
00045 #include "nsCRT.h"
00046 
00047 #define MIME_SUPERCLASS mimeObjectClass
00048 MimeDefClass(MimeLeaf, MimeLeafClass, mimeLeafClass, &MIME_SUPERCLASS);
00049 
00050 static int MimeLeaf_initialize (MimeObject *);
00051 static void MimeLeaf_finalize (MimeObject *);
00052 static int MimeLeaf_parse_begin (MimeObject *);
00053 static int MimeLeaf_parse_buffer (const char *, PRInt32, MimeObject *);
00054 static int MimeLeaf_parse_line (char *, PRInt32, MimeObject *);
00055 static int MimeLeaf_close_decoder (MimeObject *);
00056 static int MimeLeaf_parse_eof (MimeObject *, PRBool);
00057 static PRBool MimeLeaf_displayable_inline_p (MimeObjectClass *clazz,
00058                                                                                MimeHeaders *hdrs);
00059 
00060 static int
00061 MimeLeafClassInitialize(MimeLeafClass *clazz)
00062 {
00063   MimeObjectClass *oclass = (MimeObjectClass *) clazz;
00064   NS_ASSERTION(!oclass->class_initialized, "1.1 <rhp@netscape.com> 19 Mar 1999 12:00");
00065   oclass->initialize   = MimeLeaf_initialize;
00066   oclass->finalize     = MimeLeaf_finalize;
00067   oclass->parse_begin  = MimeLeaf_parse_begin;
00068   oclass->parse_buffer = MimeLeaf_parse_buffer;
00069   oclass->parse_line   = MimeLeaf_parse_line;
00070   oclass->parse_eof    = MimeLeaf_parse_eof;
00071   oclass->displayable_inline_p = MimeLeaf_displayable_inline_p;
00072   clazz->close_decoder = MimeLeaf_close_decoder;
00073 
00074   /* Default `parse_buffer' method is one which line-buffers the now-decoded
00075         data and passes it on to `parse_line'.  (We snarf the implementation of
00076         this method from our superclass's implementation of `parse_buffer', which
00077         inherited it from MimeObject.)
00078    */
00079   clazz->parse_decoded_buffer =
00080        ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_buffer;
00081 
00082   return 0;
00083 }
00084 
00085 
00086 static int
00087 MimeLeaf_initialize (MimeObject *obj)
00088 {
00089   /* This is an abstract class; it shouldn't be directly instantiated. */
00090   NS_ASSERTION(obj->clazz != (MimeObjectClass *) &mimeLeafClass, "1.1 <rhp@netscape.com> 19 Mar 1999 12:00");
00091 
00092   return ((MimeObjectClass*)&MIME_SUPERCLASS)->initialize(obj);
00093 }
00094 
00095 
00096 static void
00097 MimeLeaf_finalize (MimeObject *object)
00098 {
00099   MimeLeaf *leaf = (MimeLeaf *)object;
00100   object->clazz->parse_eof (object, PR_FALSE);
00101 
00102   /* Free the decoder data, if it's still around.  It was probably freed
00103         in MimeLeaf_parse_eof(), but just in case... */
00104   if (leaf->decoder_data)
00105        {
00106          MimeDecoderDestroy(leaf->decoder_data, PR_TRUE);
00107          leaf->decoder_data = 0;
00108        }
00109 
00110   ((MimeObjectClass*)&MIME_SUPERCLASS)->finalize (object);
00111 }
00112 
00113 
00114 static int
00115 MimeLeaf_parse_begin (MimeObject *obj)
00116 {
00117   MimeLeaf *leaf = (MimeLeaf *) obj;
00118   MimeDecoderData *(*fn) (nsresult (*) (const char*, PRInt32, void*), void*) = 0;
00119 
00120   /* Initialize a decoder if necessary.
00121    */
00122   if (!obj->encoding)
00123        ;
00124   else if (!nsCRT::strcasecmp(obj->encoding, ENCODING_BASE64))
00125        fn = &MimeB64DecoderInit;
00126   else if (!nsCRT::strcasecmp(obj->encoding, ENCODING_QUOTED_PRINTABLE))
00127        leaf->decoder_data = 
00128           MimeQPDecoderInit(((nsresult (*) (const char *, PRInt32, void *))
00129                         ((MimeLeafClass *)obj->clazz)->parse_decoded_buffer),
00130                         obj, obj);
00131   else if (!nsCRT::strcasecmp(obj->encoding, ENCODING_UUENCODE) ||
00132                  !nsCRT::strcasecmp(obj->encoding, ENCODING_UUENCODE2) ||
00133                  !nsCRT::strcasecmp(obj->encoding, ENCODING_UUENCODE3) ||
00134                  !nsCRT::strcasecmp(obj->encoding, ENCODING_UUENCODE4))
00135        fn = &MimeUUDecoderInit;
00136   else if (!nsCRT::strcasecmp(obj->encoding, ENCODING_YENCODE))
00137     fn = &MimeYDecoderInit;
00138 
00139   if (fn)
00140        {
00141          leaf->decoder_data =
00142               fn (/* The (nsresult (*) ...) cast is to turn the `void' argument
00143                         into `MimeObject'. */
00144                      ((nsresult (*) (const char *, PRInt32, void *))
00145                       ((MimeLeafClass *)obj->clazz)->parse_decoded_buffer),
00146                      obj);
00147 
00148          if (!leaf->decoder_data)
00149               return MIME_OUT_OF_MEMORY;
00150        }
00151 
00152   return ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_begin(obj);
00153 }
00154 
00155 
00156 static int
00157 MimeLeaf_parse_buffer (const char *buffer, PRInt32 size, MimeObject *obj)
00158 {
00159   MimeLeaf *leaf = (MimeLeaf *) obj;
00160 
00161   NS_ASSERTION(!obj->closed_p, "1.1 <rhp@netscape.com> 19 Mar 1999 12:00");
00162   if (obj->closed_p) return -1;
00163 
00164   /* If we're not supposed to write this object, bug out now.
00165    */
00166   if (!obj->output_p ||
00167          !obj->options ||
00168          !obj->options->output_fn)
00169        return 0;
00170 
00171   if (leaf->decoder_data &&
00172       obj->options && 
00173       obj->options->format_out != nsMimeOutput::nsMimeMessageDecrypt
00174       && obj->options->format_out != nsMimeOutput::nsMimeMessageAttach)
00175        return MimeDecoderWrite (leaf->decoder_data, buffer, size);
00176   else
00177        return ((MimeLeafClass *)obj->clazz)->parse_decoded_buffer (buffer, size,
00178                                                                                                                 obj);
00179 }
00180 
00181 static int
00182 MimeLeaf_parse_line (char *line, PRInt32 length, MimeObject *obj)
00183 {
00184   NS_ASSERTION(0, "1.1 <rhp@netscape.com> 19 Mar 1999 12:00");
00185   /* This method shouldn't ever be called. */
00186   return -1;
00187 }
00188 
00189 
00190 static int
00191 MimeLeaf_close_decoder (MimeObject *obj)
00192 {
00193   MimeLeaf *leaf = (MimeLeaf *) obj;
00194 
00195   if (leaf->decoder_data)
00196   {
00197       int status = MimeDecoderDestroy(leaf->decoder_data, PR_FALSE);
00198       leaf->decoder_data = 0;
00199       return status;
00200   }
00201 
00202   return 0;
00203 }
00204 
00205 
00206 static int
00207 MimeLeaf_parse_eof (MimeObject *obj, PRBool abort_p)
00208 {
00209   MimeLeaf *leaf = (MimeLeaf *) obj;
00210   if (obj->closed_p) return 0;
00211 
00212   /* Close off the decoder, to cause it to give up any buffered data that
00213         it is still holding.
00214    */
00215   if (leaf->decoder_data)
00216   {
00217       int status = MimeLeaf_close_decoder(obj);
00218       if (status < 0) return status;
00219   }
00220 
00221   /* Now run the superclass's parse_eof, which will force out the line
00222         buffer (which we may have just repopulated, above.)
00223    */
00224   return ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_eof (obj, abort_p);
00225 }
00226 
00227 
00228 static PRBool
00229 MimeLeaf_displayable_inline_p (MimeObjectClass *clazz, MimeHeaders *hdrs)
00230 {
00231   return PR_TRUE;
00232 }