Back to index

lightning-sunbird  0.9+nobinonly
Classes | Typedefs | Functions | Variables
mimetric.h File Reference
#include "mimetext.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  MimeInlineTextRichtextClass
struct  MimeInlineTextRichtext

Typedefs

typedef struct MimeInlineTextRichtextClass
typedef struct MimeInlineTextRichtext

Functions

int MimeRichtextConvert (char *line, PRInt32 length, int(*output_fn)(const char *buf, PRInt32 size, void *closure), void *closure, char **obufferP, PRInt32 *obuffer_sizeP, PRBool enriched_p)

Variables

MimeInlineTextRichtextClass mimeInlineTextRichtextClass

Class Documentation

struct MimeInlineTextRichtextClass

Definition at line 51 of file mimetric.h.

Class Members
PRBool enriched_p
MimeInlineTextClass text
struct MimeInlineTextRichtext

Definition at line 58 of file mimetric.h.

Class Members
MimeInlineText text

Typedef Documentation

typedef struct MimeInlineTextRichtext

Definition at line 49 of file mimetric.h.

Definition at line 48 of file mimetric.h.


Function Documentation

int MimeRichtextConvert ( char *  line,
PRInt32  length,
int(*)(const char *buf, PRInt32 size, void *closure output_fn,
void closure,
char **  obufferP,
PRInt32 obuffer_sizeP,
PRBool  enriched_p 
)

Definition at line 68 of file mimetric.cpp.

{
  /* RFC 1341 (the original MIME spec) defined text/richtext.
        RFC 1563 superceded text/richtext with text/enriched.
        The changes from text/richtext to text/enriched are:
         - CRLF semantics are different
         - << maps to <
         - These tags were added:
            <VERBATIM>, <NOFILL>, <PARAM>, <FLUSHBOTH>
         - These tags were removed:
            <COMMENT>, <OUTDENT>, <OUTDENTRIGHT>, <SAMEPAGE>, <SUBSCRIPT>,
         <SUPERSCRIPT>, <HEADING>, <FOOTING>, <PARAGRAPH>, <SIGNATURE>,
            <LT>, <NL>, <NP>
        This method implements them both.

        draft-resnick-text-enriched-03.txt is a proposed update to 1563.
         - These tags were added:
           <FONTFAMILY>, <COLOR>, <PARAINDENT>, <LANG>.
              However, all of these rely on the magic <PARAM> tag, which we
              don't implement, so we're ignoring all of these.
        Interesting fact: it's by Peter W. Resnick from Qualcomm (Eudora).
        And it also says "It is fully expected that other text formatting
        standards like HTML and SGML will supplant text/enriched in
        Internet mail."
   */
  int status = 0;
  char *out;
  const char *data_end;
  const char *last_end;
  const char *this_start;
  const char *this_end;
  unsigned int desired_size;

  // The code below must never expand the input by more than 5x;
  // if it does, the desired_size multiplier (5) below must be changed too
#define BGROWTH 5
  if ( (PRUint32)length >= ( (PRUint32) 0xfffffffe)/BGROWTH )
      return -1;
  desired_size = (length * BGROWTH) + 1;
#undef BGROWTH  
  if (desired_size >= (PRUint32) *obuffer_sizeP)
       status = mime_GrowBuffer (desired_size, sizeof(char), 1024,
                                                  obufferP, obuffer_sizeP);
  if (status < 0) return status;

  if (enriched_p)
       {
         for (this_start = line; this_start < line + length; this_start++)
              if (!nsCRT::IsAsciiSpace (*this_start)) break;
         if (this_start >= line + length) /* blank line */
              {
                PL_strncpyz (*obufferP, "<BR>", *obuffer_sizeP);
                return output_fn (*obufferP, strlen(*obufferP), closure);
              }
       }

  PRUint32 outlen = (PRUint32) *obuffer_sizeP;
  out = *obufferP;
  *out = 0;

  data_end = line + length;
  last_end = line;
  this_start = last_end;
  this_end = this_start;
  PRUint32 addedlen = 0;
  while (this_end < data_end)
       {
         /* Skip forward to next special character. */
         while (this_start < data_end &&
                      *this_start != '<' && *this_start != '>' &&
                      *this_start != '&')
              this_start++;

         this_end = this_start;

         /* Skip to the end of the tag. */
         if (this_start < data_end && *this_start == '<')
              {
                this_end++;
                while (this_end < data_end &&
                             !nsCRT::IsAsciiSpace (*this_end) &&
                             *this_end != '<' && *this_end != '>' &&
                             *this_end != '&')
                     this_end++;
              }

         this_end++;

         /* Push out the text preceeding the tag. */
         if (last_end && last_end != this_start)
              {
                memcpy (out, last_end, this_start - last_end);
                out += this_start - last_end;
                *out = 0;
                outlen -= (this_start - last_end);
              }

         if (this_start >= data_end)
              break;
         else if (*this_start == '&')
              {
                PL_strncpyz (out, "&amp;", outlen);
                addedlen = strlen(out);
                outlen -= addedlen;
                out += addedlen;
              }
         else if (*this_start == '>')
              {
                PL_strncpyz (out, "&gt;", outlen);
                addedlen = strlen(out);
                outlen -= addedlen;
                out += addedlen;
              }
         else if (enriched_p &&
                        this_start < data_end + 1 &&
                        this_start[0] == '<' &&
                        this_start[1] == '<')
              {
                PL_strncpyz (out, "&lt;", outlen);
                addedlen = strlen(out);
                outlen -= addedlen;
                out += addedlen;
              }
         else if (this_start != this_end)
              {
                /* Push out this ID. */
                const char *old = this_start + 1;
                char *tag_open  = 0;
                char *tag_close = 0;
                if (*old == '/')
                     {
                       /* This is </tag> */
                       old++;
                     }

                switch (*old)
                     {
                     case 'b': case 'B':
                       if (!nsCRT::strncasecmp ("BIGGER>", old, 7))
                            tag_open = "<FONT SIZE=\"+1\">", tag_close = "</FONT>";
                       else if (!nsCRT::strncasecmp ("BLINK>", old, 5))
                            /* Of course, both text/richtext and text/enriched must be
                               enhanced *somehow*...  Or else what would people think. */
                            tag_open = "<BLINK>", tag_close = "</BLINK>";
                       else if (!nsCRT::strncasecmp ("BOLD>", old, 5))
                            tag_open = "<B>", tag_close = "</B>";
                       break;
                     case 'c': case 'C':
                       if (!nsCRT::strncasecmp ("CENTER>", old, 7))
                            tag_open = "<CENTER>", tag_close = "</CENTER>";
                       else if (!enriched_p &&
                                      !nsCRT::strncasecmp ("COMMENT>", old, 8))
                            tag_open = "<!-- ", tag_close = " -->";
                       break;
                     case 'e': case 'E':
                       if (!nsCRT::strncasecmp ("EXCERPT>", old, 8))
                            tag_open = "<BLOCKQUOTE>", tag_close = "</BLOCKQUOTE>";
                       break;
                     case 'f': case 'F':
                       if (!nsCRT::strncasecmp ("FIXED>", old, 6))
                            tag_open = "<TT>", tag_close = "</TT>";
                       else if (enriched_p &&
                                      !nsCRT::strncasecmp ("FLUSHBOTH>", old, 10))
                            tag_open = "<P ALIGN=LEFT>", tag_close = "</P>";
                       else if (!nsCRT::strncasecmp ("FLUSHLEFT>", old, 10))
                            tag_open = "<P ALIGN=LEFT>", tag_close = "</P>";
                       else if (!nsCRT::strncasecmp ("FLUSHRIGHT>", old, 11))
                            tag_open = "<P ALIGN=RIGHT>", tag_close = "</P>";
                       else if (!enriched_p &&
                                      !nsCRT::strncasecmp ("FOOTING>", old, 8))
                            tag_open = "<H6>", tag_close = "</H6>";
                       break;
                     case 'h': case 'H':
                       if (!enriched_p &&
                              !nsCRT::strncasecmp ("HEADING>", old, 8))
                            tag_open = "<H6>", tag_close = "</H6>";
                       break;
                     case 'i': case 'I':
                       if (!nsCRT::strncasecmp ("INDENT>", old, 7))
                            tag_open = "<UL>", tag_close = "</UL>";
                       else if (!nsCRT::strncasecmp ("INDENTRIGHT>", old, 12))
                            tag_open = 0, tag_close = 0;
/*                     else if (!enriched_p &&
                                   !nsCRT::strncasecmp ("ISO-8859-", old, 9))
                            tag_open = 0, tag_close = 0; */
                       else if (!nsCRT::strncasecmp ("ITALIC>", old, 7))
                            tag_open = "<I>", tag_close = "</I>";
                       break;
                     case 'l': case 'L':
                       if (!enriched_p &&
                              !nsCRT::strncasecmp ("LT>", old, 3))
                            tag_open = "&lt;", tag_close = 0;
                       break;
                     case 'n': case 'N':
                       if (!enriched_p &&
                              !nsCRT::strncasecmp ("NL>", old, 3))
                            tag_open = "<BR>", tag_close = 0;
                       if (enriched_p &&
                              !nsCRT::strncasecmp ("NOFILL>", old, 7))
                            tag_open = "<NOBR>", tag_close = "</NOBR>";
/*                     else if (!enriched_p &&
                                   !nsCRT::strncasecmp ("NO-OP>", old, 6))
                            tag_open = 0, tag_close = 0; */
/*                     else if (!enriched_p &&
                                   !nsCRT::strncasecmp ("NP>", old, 3))
                            tag_open = 0, tag_close = 0; */
                       break;
                     case 'o': case 'O':
                       if (!enriched_p &&
                              !nsCRT::strncasecmp ("OUTDENT>", old, 8))
                            tag_open = 0, tag_close = 0;
                       else if (!enriched_p &&
                                      !nsCRT::strncasecmp ("OUTDENTRIGHT>", old, 13))
                            tag_open = 0, tag_close = 0;
                       break;
                     case 'p': case 'P':
                       if (enriched_p &&
                              !nsCRT::strncasecmp ("PARAM>", old, 6))
                            tag_open = "<!-- ", tag_close = " -->";
                       else if (!enriched_p &&
                                      !nsCRT::strncasecmp ("PARAGRAPH>", old, 10))
                            tag_open = "<P>", tag_close = 0;
                       break;
                     case 's': case 'S':
                       if (!enriched_p &&
                              !nsCRT::strncasecmp ("SAMEPAGE>", old, 9))
                            tag_open = 0, tag_close = 0;
                       else if (!enriched_p &&
                                      !nsCRT::strncasecmp ("SIGNATURE>", old, 10))
                            tag_open = "<I><FONT SIZE=\"-1\">", tag_close = "</FONT></I>";
                       else if (!nsCRT::strncasecmp ("SMALLER>", old, 8))
                            tag_open = "<FONT SIZE=\"-1\">", tag_close = "</FONT>";
                       else if (!enriched_p &&
                                      !nsCRT::strncasecmp ("SUBSCRIPT>", old, 10))
                            tag_open = "<SUB>", tag_close = "</SUB>";
                       else if (!enriched_p &&
                                      !nsCRT::strncasecmp ("SUPERSCRIPT>", old, 12))
                            tag_open = "<SUP>", tag_close = "</SUP>";
                       break;
                     case 'u': case 'U':
                       if (!nsCRT::strncasecmp ("UNDERLINE>", old, 10))
                            tag_open = "<U>", tag_close = "</U>";
/*                     else if (!enriched_p &&
                                      !nsCRT::strncasecmp ("US-ASCII>", old, 10))
                            tag_open = 0, tag_close = 0; */
                       break;
                     case 'v': case 'V':
                       if (enriched_p &&
                              !nsCRT::strncasecmp ("VERBATIM>", old, 9))
                            tag_open = "<PRE>", tag_close = "</PRE>";
                       break;
                     }

                if (this_start[1] == '/')
                     {
                       if (tag_close) PL_strncpyz (out, tag_close, outlen);
                       addedlen = strlen (out);
                       outlen -= addedlen;
                       out += addedlen;
                     }
                else
                     {
                       if (tag_open) PL_strncpyz (out, tag_open, outlen);
                       addedlen = strlen (out);
                       outlen -= addedlen;
                       out += addedlen;
                     }
              }

         /* now go around again */
         last_end = this_end;
         this_start = last_end;
       }
  *out = 0;

  return output_fn (*obufferP, out - *obufferP, closure);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation