Back to index

lightning-sunbird  0.9+nobinonly
mimeiimg.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 #include "nsCOMPtr.h"
00038 #include "mimeiimg.h"
00039 #include "mimemoz2.h"
00040 #include "prmem.h"
00041 #include "plstr.h"
00042 #include "prlog.h"
00043 #include "nsMimeTypes.h"
00044 #include "nsMimeStringResources.h"
00045 #include "nsCRT.h"
00046 #include "nsEscape.h"
00047 
00048 #define MIME_SUPERCLASS mimeLeafClass
00049 MimeDefClass(MimeInlineImage, MimeInlineImageClass,
00050                       mimeInlineImageClass, &MIME_SUPERCLASS);
00051 
00052 static int MimeInlineImage_initialize (MimeObject *);
00053 static void MimeInlineImage_finalize (MimeObject *);
00054 static int MimeInlineImage_parse_begin (MimeObject *);
00055 static int MimeInlineImage_parse_line (char *, PRInt32, MimeObject *);
00056 static int MimeInlineImage_parse_eof (MimeObject *, PRBool);
00057 static int MimeInlineImage_parse_decoded_buffer (const char *, PRInt32, MimeObject *);
00058 
00059 static int
00060 MimeInlineImageClassInitialize(MimeInlineImageClass *clazz)
00061 {
00062   MimeObjectClass *oclass = (MimeObjectClass *) clazz;
00063   MimeLeafClass   *lclass = (MimeLeafClass *) clazz;
00064 
00065   NS_ASSERTION(!oclass->class_initialized, "1.1 <rhp@netscape.com> 19 Mar 1999 12:00");
00066   oclass->initialize   = MimeInlineImage_initialize;
00067   oclass->finalize     = MimeInlineImage_finalize;
00068   oclass->parse_begin  = MimeInlineImage_parse_begin;
00069   oclass->parse_line   = MimeInlineImage_parse_line;
00070   oclass->parse_eof    = MimeInlineImage_parse_eof;
00071   lclass->parse_decoded_buffer = MimeInlineImage_parse_decoded_buffer;
00072 
00073   return 0;
00074 }
00075 
00076 
00077 static int
00078 MimeInlineImage_initialize (MimeObject *object)
00079 {
00080   return ((MimeObjectClass*)&MIME_SUPERCLASS)->initialize(object);
00081 }
00082 
00083 static void
00084 MimeInlineImage_finalize (MimeObject *object)
00085 {
00086   ((MimeObjectClass*)&MIME_SUPERCLASS)->finalize(object);
00087 }
00088 
00089 static int
00090 MimeInlineImage_parse_begin (MimeObject *obj)
00091 {
00092   MimeInlineImage *img = (MimeInlineImage *) obj;
00093   MimeInlineImageClass *clazz;
00094 
00095   int status;
00096 
00097   status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_begin(obj);
00098   if (status < 0) return status;
00099 
00100   if (!obj->output_p) return 0;
00101 
00102   if (!obj->options || !obj->options->output_fn)
00103     return 0;
00104 
00105   clazz = (MimeInlineImageClass *) obj->clazz;
00106 
00107   if (obj->options &&
00108     obj->options->image_begin &&
00109     obj->options->write_html_p &&
00110     obj->options->image_write_buffer)
00111   {
00112     char *html, *part, *image_url;
00113     const char *ct;
00114 
00115     part = mime_part_address(obj);
00116     if (!part) return MIME_OUT_OF_MEMORY;
00117     
00118       char *no_part_url = nsnull;
00119       if (obj->options->part_to_load && obj->options->format_out == nsMimeOutput::nsMimeMessageBodyDisplay)
00120         no_part_url = mime_get_base_url(obj->options->url);
00121 
00122         if (no_part_url)
00123         {
00124           image_url = mime_set_url_part(no_part_url, part, PR_TRUE);
00125           PR_Free(no_part_url);
00126         }
00127         else
00128           image_url = mime_set_url_part(obj->options->url, part, PR_TRUE);
00129 
00130     if (!image_url)
00131     {
00132                 PR_Free(part);
00133       return MIME_OUT_OF_MEMORY;
00134     }
00135     PR_Free(part);
00136     
00137     ct = obj->content_type;
00138     if (!ct) ct = IMAGE_GIF;  /* Can't happen?  Close enough. */
00139 
00140          // Fill in content type and attachment name here.
00141     nsCAutoString url_with_filename(image_url);
00142     url_with_filename += "&type=";
00143     url_with_filename += ct;
00144     char * filename = MimeHeaders_get_name ( obj->headers, obj->options );
00145     if (filename)
00146     {
00147       char *escapedName = nsEscape(filename, url_Path);
00148       if (!escapedName) return MIME_OUT_OF_MEMORY;
00149       url_with_filename += "&filename=";
00150       url_with_filename += escapedName;
00151       nsCRT::free(escapedName);
00152       PR_Free(filename);
00153     }
00154 
00155     // We need to separate images with HR's...
00156     MimeObject_write_separator(obj);
00157 
00158          img->image_data =
00159       obj->options->image_begin(url_with_filename.get(), ct, obj->options->stream_closure);
00160     PR_Free(image_url);
00161 
00162     if (!img->image_data) return MIME_OUT_OF_MEMORY;
00163 
00164     html = obj->options->make_image_html(img->image_data);
00165     if (!html) return MIME_OUT_OF_MEMORY;
00166 
00167     status = MimeObject_write(obj, html, strlen(html), PR_TRUE);
00168     PR_Free(html);
00169     if (status < 0) return status;
00170   }
00171 
00172   // 
00173   // Now we are going to see if we should set the content type in the
00174   // URI for the url being run...
00175   //
00176   if (obj->options && obj->options->stream_closure && obj->content_type)
00177   {
00178     mime_stream_data  *msd = (mime_stream_data *) (obj->options->stream_closure);
00179     if ( (msd) && (msd->channel) )
00180     {
00181       msd->channel->SetContentType(nsDependentCString(obj->content_type));
00182     }
00183   }
00184 
00185   return 0;
00186 }
00187 
00188 
00189 static int
00190 MimeInlineImage_parse_eof (MimeObject *obj, PRBool abort_p)
00191 {
00192   MimeInlineImage *img = (MimeInlineImage *) obj;
00193   int status;
00194   if (obj->closed_p) return 0;
00195 
00196   /* Force out any buffered data from the superclass (the base64 decoder.) */
00197   status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_eof(obj, abort_p);
00198   if (status < 0) abort_p = PR_TRUE;
00199 
00200   if (img->image_data)
00201        {
00202          obj->options->image_end(img->image_data,
00203                                                    (status < 0 ? status : (abort_p ? -1 : 0)));
00204          img->image_data = 0;
00205        }
00206 
00207   return status;
00208 }
00209 
00210 
00211 static int
00212 MimeInlineImage_parse_decoded_buffer (const char *buf, PRInt32 size, MimeObject *obj)
00213 {
00214   /* This is called (by MimeLeafClass->parse_buffer) with blocks of data
00215         that have already been base64-decoded.  Pass this raw image data
00216         along to the backend-specific image display code.
00217    */
00218   MimeInlineImage *img  = (MimeInlineImage *) obj;
00219   int status;
00220 
00221   if (obj->output_p &&
00222          obj->options &&
00223          !obj->options->write_html_p)
00224        {
00225          /* in this case, we just want the raw data...
00226                Make the stream, if it's not made, and dump the data out.
00227           */
00228 
00229          if (!obj->options->state->first_data_written_p)
00230               {
00231                 status = MimeObject_output_init(obj, 0);
00232                 if (status < 0) return status;
00233                 NS_ASSERTION(obj->options->state->first_data_written_p, "1.1 <rhp@netscape.com> 19 Mar 1999 12:00");
00234               }
00235          
00236          return MimeObject_write(obj, buf, size, PR_TRUE);
00237        }
00238 
00239 
00240   if (!obj->options ||
00241          !obj->options->image_write_buffer)
00242        return 0;
00243 
00244   /* If we don't have any image data, the image_end method must have already
00245         been called, so don't call image_write_buffer again. */
00246   if (!img->image_data) return 0;
00247 
00248   /* Hand this data off to the backend-specific image display stream.
00249    */
00250   status = obj->options->image_write_buffer (buf, size, img->image_data);
00251   
00252   /* If the image display stream fails, then close the stream - but do not
00253         return the failure status, and do not give up on parsing this object.
00254         Just because the image data was corrupt doesn't mean we need to give up
00255         on the whole document; we can continue by just skipping over the rest of
00256         this part, and letting our parent continue.
00257    */
00258   if (status < 0)
00259        {
00260          obj->options->image_end (img->image_data, status);
00261          img->image_data = 0;
00262          status = 0;
00263        }
00264 
00265   return status;
00266 }
00267 
00268 
00269 static int
00270 MimeInlineImage_parse_line (char *line, PRInt32 length, MimeObject *obj)
00271 {
00272   /* This method should never be called (inline images do no line buffering).
00273    */
00274   NS_ASSERTION(0, "1.1 <rhp@netscape.com> 19 Mar 1999 12:00");
00275   return -1;
00276 }