Back to index

lightning-sunbird  0.9+nobinonly
mimethtm.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 "mimethtm.h"
00038 #include "prmem.h"
00039 #include "plstr.h"
00040 #include "prlog.h"
00041 #include "prprf.h"
00042 #include "msgCore.h"
00043 #include "nsMimeStringResources.h"
00044 #include "mimemoz2.h"
00045 
00046 #define MIME_SUPERCLASS mimeInlineTextClass
00047 MimeDefClass(MimeInlineTextHTML, MimeInlineTextHTMLClass,
00048                       mimeInlineTextHTMLClass, &MIME_SUPERCLASS);
00049 
00050 static int MimeInlineTextHTML_parse_line (char *, PRInt32, MimeObject *);
00051 static int MimeInlineTextHTML_parse_eof (MimeObject *, PRBool);
00052 static int MimeInlineTextHTML_parse_begin (MimeObject *obj);
00053 
00054 static int
00055 MimeInlineTextHTMLClassInitialize(MimeInlineTextHTMLClass *clazz)
00056 {
00057   MimeObjectClass *oclass = (MimeObjectClass *) clazz;
00058   PR_ASSERT(!oclass->class_initialized);
00059   oclass->parse_begin = MimeInlineTextHTML_parse_begin;
00060   oclass->parse_line  = MimeInlineTextHTML_parse_line;
00061   oclass->parse_eof   = MimeInlineTextHTML_parse_eof;
00062 
00063   return 0;
00064 }
00065 
00066 static int
00067 MimeInlineTextHTML_parse_begin (MimeObject *obj)
00068 {
00069   int status = ((MimeObjectClass*)&mimeLeafClass)->parse_begin(obj);
00070   if (status < 0) return status;
00071   
00072   if (!obj->output_p) return 0;
00073 
00074   // Set a default font (otherwise unicode font will be used since the data is UTF-8).
00075   if (nsMimeOutput::nsMimeMessageBodyDisplay == obj->options->format_out ||
00076       nsMimeOutput::nsMimeMessagePrintOutput == obj->options->format_out)
00077   {
00078     char buf[256];            // local buffer for html tag
00079     PRInt32 fontSize;         // default font size
00080     PRInt32 fontSizePercentage;   // size percentage
00081     nsCAutoString fontLang;       // langgroup of the font. 
00082     if (NS_SUCCEEDED(GetMailNewsFont(obj, PR_FALSE, &fontSize, &fontSizePercentage,fontLang)))
00083     {
00084       PR_snprintf(buf, 256, "<div class=\"moz-text-html\"  lang=\"%s\">", 
00085                   fontLang.get());
00086       status = MimeObject_write(obj, buf, strlen(buf), PR_FALSE);
00087     }
00088     else
00089     {
00090       status = MimeObject_write(obj, "<div class=\"moz-text-html\">", 27, PR_FALSE);
00091     }
00092     if(status<0) return status;
00093   }
00094 
00095   MimeInlineTextHTML  *textHTML = (MimeInlineTextHTML *) obj;
00096   
00097   textHTML->charset = nsnull;
00098   
00099   /* If this HTML part has a Content-Base header, and if we're displaying
00100         to the screen (that is, not writing this part "raw") then translate
00101    that Content-Base header into a <BASE> tag in the HTML.
00102   */
00103   if (obj->options &&
00104     obj->options->write_html_p &&
00105     obj->options->output_fn)
00106   {
00107     char *base_hdr = MimeHeaders_get (obj->headers, HEADER_CONTENT_BASE,
00108       PR_FALSE, PR_FALSE);
00109     
00110     /* rhp - for MHTML Spec changes!!! */
00111     if (!base_hdr)
00112     {
00113       base_hdr = MimeHeaders_get (obj->headers, HEADER_CONTENT_LOCATION, PR_FALSE, PR_FALSE);
00114     }
00115     /* rhp - for MHTML Spec changes!!! */
00116     
00117     if (base_hdr)
00118     {
00119       PRUint32 buflen = strlen(base_hdr) + 20;
00120       char *buf = (char *) PR_MALLOC(buflen);
00121       const char *in;
00122       char *out;
00123       if (!buf)
00124         return MIME_OUT_OF_MEMORY;
00125       
00126         /* The value of the Content-Base header is a number of "words".
00127         Whitespace in this header is not significant -- it is assumed
00128         that any real whitespace in the URL has already been encoded,
00129         and whitespace has been inserted to allow the lines in the
00130         mail header to be wrapped reasonably.  Creators are supposed
00131         to insert whitespace every 40 characters or less.
00132       */
00133       PL_strncpyz(buf, "<BASE HREF=\"", buflen);
00134       out = buf + strlen(buf);
00135       
00136       for (in = base_hdr; *in; in++)
00137         /* ignore whitespace and quotes */
00138         if (!nsCRT::IsAsciiSpace(*in) && *in != '"')
00139           *out++ = *in;
00140         
00141         /* Close the tag and argument. */
00142         *out++ = '"';
00143         *out++ = '>';
00144         *out++ = 0;
00145         
00146         PR_Free(base_hdr);
00147         
00148         status = MimeObject_write(obj, buf, strlen(buf), PR_FALSE);
00149         PR_Free(buf);
00150         if (status < 0) return status;
00151     }
00152   }
00153   
00154   // rhp: For a change, we will write out a separator after formatted text
00155   //      bodies.
00156   status = MimeObject_write_separator(obj);
00157   if (status < 0) return status;
00158   
00159   return 0;
00160 }
00161 
00162 
00163 static int
00164 MimeInlineTextHTML_parse_line (char *line, PRInt32 length, MimeObject *obj)
00165 {
00166   MimeInlineTextHTML  *textHTML = (MimeInlineTextHTML *) obj;
00167 
00168   if (!obj->output_p) 
00169     return 0;
00170 
00171   if (!obj->options || !obj->options->output_fn)
00172     return 0;
00173 
00174   if (!textHTML->charset)
00175   {
00176     char * cp;
00177     // First, try to detect a charset via a META tag!
00178     if ((cp = PL_strncasestr(line, "META", length)) && 
00179         (cp = PL_strncasestr(cp, "HTTP-EQUIV=", length - (int)(cp - line))) && 
00180         (cp = PL_strncasestr(cp, "CONTENT=", length - (int)(cp - line))) && 
00181         (cp = PL_strncasestr(cp, "CHARSET=", length - (int)(cp - line))) 
00182         ) 
00183     {
00184       char* cp1 = cp + 8;  //8 for the length of "CHARSET="
00185       char* cp2 = PL_strnpbrk(cp1, " \"\'", length - (int)(cp1 - line));
00186       if (cp2)
00187       {
00188         char* charset = PL_strndup(cp1, (int)(cp2 - cp1));
00189  
00190         // Fix bug 101434, in this case since this parsing is a char* 
00191         // operation, a real UTF-16 or UTF-32 document won't be parse 
00192         // correctly, if it got parse, it cannot be UTF-16 nor UTF-32
00193         // there fore, we ignore them if somehow we got that value
00194         // 6 == strlen("UTF-16") or strlen("UTF-32"), this will cover
00195         // UTF-16, UTF-16BE, UTF-16LE, UTF-32, UTF-32BE, UTF-32LE
00196         if ((charset != nsnull) &&
00197             nsCRT::strncasecmp(charset, "UTF-16", 6) &&
00198             nsCRT::strncasecmp(charset, "UTF-32", 6))
00199         {
00200           textHTML->charset = charset; 
00201 
00202           // write out the data without the charset part...
00203           if (textHTML->charset)
00204           {
00205             int err = MimeObject_write(obj, line, cp - line, PR_TRUE);
00206             if (err == 0)
00207               err = MimeObject_write(obj, cp2, length - (int)(cp2 - line), PR_TRUE);
00208 
00209             return err;
00210           }
00211         }
00212         PR_FREEIF(charset);
00213       }
00214     }
00215   }
00216 
00217   // Now, just write out the data...
00218   return MimeObject_write(obj, line, length, PR_TRUE);
00219 }
00220 
00221 static int
00222 MimeInlineTextHTML_parse_eof (MimeObject *obj, PRBool abort_p)
00223 {
00224   int status;
00225   MimeInlineTextHTML  *textHTML = (MimeInlineTextHTML *) obj;
00226   if (obj->closed_p) return 0;
00227 
00228   PR_FREEIF(textHTML->charset);
00229 
00230   /* Run parent method first, to flush out any buffered data. */
00231   status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_eof(obj, abort_p);
00232   if (status < 0) return status;
00233 
00234   if (nsMimeOutput::nsMimeMessageBodyDisplay == obj->options->format_out ||
00235       nsMimeOutput::nsMimeMessagePrintOutput == obj->options->format_out)
00236     status = MimeObject_write(obj, "</div>", 6, PR_FALSE);
00237 
00238   return 0;
00239 }