More cleanup for modular libmime.

This commit is contained in:
rhp%netscape.com 1999-01-29 16:48:29 +00:00
Родитель 30fd516d31
Коммит 6fb30ce75f
11 изменённых файлов: 151 добавлений и 1523 удалений

Просмотреть файл

@ -96,6 +96,7 @@ OBJS= \
.\$(OBJDIR)\mimeunty.obj \
.\$(OBJDIR)\mimemoz.obj \
.\$(OBJDIR)\mimecth.obj \
.\$(OBJDIR)\mimebuf.obj \
#
# THIS WILL NEED WORK AFTER WE GET A LIBMSG MORE XP-COM-afied
# .\$(OBJDIR)\mimedrft.obj \
@ -106,7 +107,6 @@ OBJS= \
# WHEN NEW WORLD FUNCTIONS ARE FOUND
.\$(OBJDIR)\oldnet.obj \
.\$(OBJDIR)\oldi18n.obj \
.\$(OBJDIR)\oldmsg.obj \
.\$(OBJDIR)\oldmaddr.obj \
.\$(OBJDIR)\oldfile.obj \
.\$(OBJDIR)\oldxp.obj \

Просмотреть файл

@ -1,241 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* mimebuf.c - libmsg like buffer handling routines for libmime
*/
#include "xp.h"
#include "prmem.h"
#include "plstr.h"
extern int MK_OUT_OF_MEMORY;
int
msg_GrowBuffer (PRUint32 desired_size, PRUint32 element_size, PRUint32 quantum,
char **buffer, PRUint32 *size)
{
if (*size <= desired_size)
{
char *new_buf;
PRUint32 increment = desired_size - *size;
if (increment < quantum) /* always grow by a minimum of N bytes */
increment = quantum;
new_buf = (*buffer
? (char *) PR_Realloc (*buffer, (*size + increment)
* (element_size / sizeof(char)))
: (char *) PR_MALLOC ((*size + increment)
* (element_size / sizeof(char))));
if (! new_buf)
return MK_OUT_OF_MEMORY;
*buffer = new_buf;
*size += increment;
}
return 0;
}
/* The opposite of msg_LineBuffer(): takes small buffers and packs them
up into bigger buffers before passing them along.
Pass in a desired_buffer_size 0 to tell it to flush (for example, in
in the very last call to this function.)
*/
int
msg_ReBuffer (const char *net_buffer, PRInt32 net_buffer_size,
PRUint32 desired_buffer_size,
char **bufferP, PRUint32 *buffer_sizeP, PRUint32 *buffer_fpP,
PRInt32 (*per_buffer_fn) (char *buffer, PRUint32 buffer_size,
void *closure),
void *closure)
{
int status = 0;
if (desired_buffer_size >= (*buffer_sizeP))
{
status = msg_GrowBuffer (desired_buffer_size, sizeof(char), 1024,
bufferP, buffer_sizeP);
if (status < 0) return status;
}
do
{
PRInt32 size = *buffer_sizeP - *buffer_fpP;
if (size > net_buffer_size)
size = net_buffer_size;
if (size > 0)
{
XP_MEMCPY ((*bufferP) + (*buffer_fpP), net_buffer, size);
(*buffer_fpP) += size;
net_buffer += size;
net_buffer_size -= size;
}
if (*buffer_fpP > 0 &&
*buffer_fpP >= desired_buffer_size)
{
status = (*per_buffer_fn) ((*bufferP), (*buffer_fpP), closure);
*buffer_fpP = 0;
if (status < 0) return status;
}
}
while (net_buffer_size > 0);
return 0;
}
static int
msg_convert_and_send_buffer(char* buf, int length, PRBool convert_newlines_p,
PRInt32 (*per_line_fn) (char *line,
PRUint32 line_length,
void *closure),
void *closure)
{
/* Convert the line terminator to the native form.
*/
char* newline;
PR_ASSERT(buf && length > 0);
if (!buf || length <= 0) return -1;
newline = buf + length;
PR_ASSERT(newline[-1] == CR || newline[-1] == LF);
if (newline[-1] != CR && newline[-1] != LF) return -1;
if (!convert_newlines_p)
{
}
#if (LINEBREAK_LEN == 1)
else if ((newline - buf) >= 2 &&
newline[-2] == CR &&
newline[-1] == LF)
{
/* CRLF -> CR or LF */
buf [length - 2] = LINEBREAK[0];
length--;
}
else if (newline > buf + 1 &&
newline[-1] != LINEBREAK[0])
{
/* CR -> LF or LF -> CR */
buf [length - 1] = LINEBREAK[0];
}
#else
else if (((newline - buf) >= 2 && newline[-2] != CR) ||
((newline - buf) >= 1 && newline[-1] != LF))
{
/* LF -> CRLF or CR -> CRLF */
length++;
buf[length - 2] = LINEBREAK[0];
buf[length - 1] = LINEBREAK[1];
}
#endif
return (*per_line_fn)(buf, length, closure);
}
int
msg_LineBuffer (const char *net_buffer, PRInt32 net_buffer_size,
char **bufferP, PRUint32 *buffer_sizeP, PRUint32 *buffer_fpP,
PRBool convert_newlines_p,
PRInt32 (*per_line_fn) (char *line, PRUint32 line_length,
void *closure),
void *closure)
{
int status = 0;
if (*buffer_fpP > 0 && *bufferP && (*bufferP)[*buffer_fpP - 1] == CR &&
net_buffer_size > 0 && net_buffer[0] != LF) {
/* The last buffer ended with a CR. The new buffer does not start
with a LF. This old buffer should be shipped out and discarded. */
PR_ASSERT(*buffer_sizeP > *buffer_fpP);
if (*buffer_sizeP <= *buffer_fpP) return -1;
status = msg_convert_and_send_buffer(*bufferP, *buffer_fpP,
convert_newlines_p,
per_line_fn, closure);
if (status < 0) return status;
*buffer_fpP = 0;
}
while (net_buffer_size > 0)
{
const char *net_buffer_end = net_buffer + net_buffer_size;
const char *newline = 0;
const char *s;
for (s = net_buffer; s < net_buffer_end; s++)
{
/* Move forward in the buffer until the first newline.
Stop when we see CRLF, CR, or LF, or the end of the buffer.
*But*, if we see a lone CR at the *very end* of the buffer,
treat this as if we had reached the end of the buffer without
seeing a line terminator. This is to catch the case of the
buffers splitting a CRLF pair, as in "FOO\r\nBAR\r" "\nBAZ\r\n".
*/
if (*s == CR || *s == LF)
{
newline = s;
if (newline[0] == CR)
{
if (s == net_buffer_end - 1)
{
/* CR at end - wait for the next character. */
newline = 0;
break;
}
else if (newline[1] == LF)
/* CRLF seen; swallow both. */
newline++;
}
newline++;
break;
}
}
/* Ensure room in the net_buffer and append some or all of the current
chunk of data to it. */
{
const char *end = (newline ? newline : net_buffer_end);
PRUint32 desired_size = (end - net_buffer) + (*buffer_fpP) + 1;
if (desired_size >= (*buffer_sizeP))
{
status = msg_GrowBuffer (desired_size, sizeof(char), 1024,
bufferP, buffer_sizeP);
if (status < 0) return status;
}
XP_MEMCPY ((*bufferP) + (*buffer_fpP), net_buffer, (end - net_buffer));
(*buffer_fpP) += (end - net_buffer);
}
/* Now *bufferP contains either a complete line, or as complete
a line as we have read so far.
If we have a line, process it, and then remove it from `*bufferP'.
Then go around the loop again, until we drain the incoming data.
*/
if (!newline)
return 0;
status = msg_convert_and_send_buffer(*bufferP, *buffer_fpP,
convert_newlines_p,
per_line_fn, closure);
if (status < 0) return status;
net_buffer_size -= (newline - net_buffer);
net_buffer = newline;
(*buffer_fpP) = 0;
}
return 0;
}

Просмотреть файл

@ -19,11 +19,11 @@
#ifndef _MIMEBUF_H_
#define _MIMEBUF_H_
extern int msg_GrowBuffer (PRUint32 desired_size,
extern int mime_GrowBuffer (PRUint32 desired_size,
PRUint32 element_size, PRUint32 quantum,
char **buffer, PRUint32 *size);
extern int msg_LineBuffer (const char *net_buffer, PRInt32 net_buffer_size,
extern int mime_LineBuffer (const char *net_buffer, PRInt32 net_buffer_size,
char **bufferP, PRUint32 *buffer_sizeP,
PRUint32 *buffer_fpP,
PRBool convert_newlines_p,
@ -31,7 +31,7 @@ extern int msg_LineBuffer (const char *net_buffer, PRInt32 net_buffer_size,
line_length, void *closure),
void *closure);
extern int msg_ReBuffer (const char *net_buffer, PRInt32 net_buffer_size,
extern int mime_ReBuffer (const char *net_buffer, PRInt32 net_buffer_size,
PRUint32 desired_buffer_size,
char **bufferP, PRUint32 *buffer_sizeP,
PRUint32 *buffer_fpP,

Просмотреть файл

@ -29,6 +29,7 @@
#include "msgcom.h"
#include "imap.h"
#include "prefapi.h"
#include "mimebuf.h"
extern int MK_OUT_OF_MEMORY;
extern int MK_MSG_NO_HEADERS;
@ -214,7 +215,7 @@ MimeHeaders_parse_line (const char *buffer, PRInt32 size, MimeHeaders *hdrs)
desired_size = hdrs->all_headers_fp + size + 1;
if (desired_size >= hdrs->all_headers_size)
{
status = msg_GrowBuffer (desired_size, sizeof(char), 255,
status = mime_GrowBuffer (desired_size, sizeof(char), 255,
&hdrs->all_headers, &hdrs->all_headers_size);
if (status < 0) return status;
}
@ -835,7 +836,7 @@ MimeHeaders_default_addbook_link_generator (const char *dest, void *closure,
#define MimeHeaders_grow_obuffer(hdrs, desired_size) \
((((long) (desired_size)) >= ((long) (hdrs)->obuffer_size)) ? \
msg_GrowBuffer ((desired_size), sizeof(char), 255, \
mime_GrowBuffer ((desired_size), sizeof(char), 255, \
&(hdrs)->obuffer, &(hdrs)->obuffer_size) \
: 0)

Просмотреть файл

@ -39,6 +39,7 @@
#include "mimemrel.h"
#include "mimemalt.h"
#include "xpgetstr.h"
#include "mimebuf.h"
#ifdef RICHIE_VCARD
# include "mimevcrd.h" /* for MIME_VCardConverter */
@ -67,7 +68,7 @@ extern int XP_FORWARDED_MESSAGE_ATTACHMENT;
#include "mimei.h" /* for moved MimeDisplayData struct */
#include "mimemoz.h"
#include "msgutils.h" /* for msg_MakeRebufferingStream() */
#include "mimebuf.h"
#include "prmem.h"
#include "plstr.h"
@ -78,6 +79,14 @@ extern int MK_UNABLE_TO_OPEN_TMP_FILE;
/* Arrgh. Why isn't this in a reasonable header file somewhere??? ###tw */
extern char * NET_ExplainErrorDetails (int code, ...);
/*
* RICHIE - should this still be here....
* For now, I am moving this libmsg type stuff into mimemoz.c
*/
extern NET_StreamClass *msg_MakeRebufferingStream (NET_StreamClass *next,
URL_Struct *url,
MWContext *context);
/* Interface between netlib and the top-level message/rfc822 parser:
MIME_MessageConverter()
@ -2066,7 +2075,7 @@ static int
mime_richtext_write (void *stream, const char* buf, PRInt32 size)
{
struct mime_richtext_data *data = (struct mime_richtext_data *) stream;
return msg_LineBuffer (buf, size, &data->ibuffer, &data->ibuffer_size,
return mime_LineBuffer (buf, size, &data->ibuffer, &data->ibuffer_size,
&data->ibuffer_fp, PR_FALSE, mime_richtext_write_line,
data);
}
@ -2396,3 +2405,135 @@ MIME_VCardConverter2 ( int format_out,
return stream;
}
#endif /* RICHIE_VCARD */
/* RICHIE
* HOW WILL THIS BE HANDLED GOING FORWARD????
*/
PRBool
ValidateDocData(MWContext *window_id)
{
printf("ValidateDocData not implemented, stubbed in webshell/tests/viewer/nsStubs.cpp\n");
return PR_TRUE;
}
struct msg_rebuffering_stream_data
{
PRUint32 desired_size;
char *buffer;
PRUint32 buffer_size;
PRUint32 buffer_fp;
NET_StreamClass *next_stream;
};
static PRInt32
msg_rebuffering_stream_write_next_chunk (char *buffer, PRUint32 buffer_size,
void *closure)
{
struct msg_rebuffering_stream_data *sd =
(struct msg_rebuffering_stream_data *) closure;
PR_ASSERT (sd);
if (!sd) return -1;
if (!sd->next_stream) return -1;
return (*sd->next_stream->put_block) (sd->next_stream->data_object,
buffer, buffer_size);
}
static int
msg_rebuffering_stream_write_chunk (void *stream,
const char* net_buffer,
PRInt32 net_buffer_size)
{
struct msg_rebuffering_stream_data *sd =
(struct msg_rebuffering_stream_data *) stream;
PR_ASSERT (sd);
if (!sd) return -1;
return mime_ReBuffer (net_buffer, net_buffer_size,
sd->desired_size,
&sd->buffer, &sd->buffer_size, &sd->buffer_fp,
msg_rebuffering_stream_write_next_chunk,
sd);
}
static void
msg_rebuffering_stream_abort (void *stream, int status)
{
struct msg_rebuffering_stream_data *sd =
(struct msg_rebuffering_stream_data *) stream;
if (!sd) return;
PR_FREEIF (sd->buffer);
if (sd->next_stream)
{
if (ValidateDocData(sd->next_stream->window_id)) /* otherwise doc_data is gone ! */
(*sd->next_stream->abort) (sd->next_stream->data_object, status);
PR_Free (sd->next_stream);
}
PR_Free (sd);
}
static void
msg_rebuffering_stream_complete (void *stream)
{
struct msg_rebuffering_stream_data *sd =
(struct msg_rebuffering_stream_data *) stream;
if (!sd) return;
sd->desired_size = 0;
msg_rebuffering_stream_write_chunk (stream, "", 0);
PR_FREEIF (sd->buffer);
if (sd->next_stream)
{
(*sd->next_stream->complete) (sd->next_stream->data_object);
PR_Free (sd->next_stream);
}
PR_Free (sd);
}
static unsigned int
msg_rebuffering_stream_write_ready (void *stream)
{
struct msg_rebuffering_stream_data *sd =
(struct msg_rebuffering_stream_data *) stream;
if (sd && sd->next_stream)
return ((*sd->next_stream->is_write_ready)
(sd->next_stream->data_object));
else
return (MAX_WRITE_READY);
}
NET_StreamClass *
msg_MakeRebufferingStream (NET_StreamClass *next_stream,
URL_Struct *url,
MWContext *context)
{
NET_StreamClass *stream;
struct msg_rebuffering_stream_data *sd;
PR_ASSERT (next_stream);
stream = PR_NEW (NET_StreamClass);
if (!stream) return 0;
sd = PR_NEW (struct msg_rebuffering_stream_data);
if (! sd)
{
PR_Free (stream);
return 0;
}
memset (sd, 0, sizeof(*sd));
memset (stream, 0, sizeof(*stream));
sd->next_stream = next_stream;
sd->desired_size = 10240;
stream->name = "ReBuffering Stream";
stream->complete = msg_rebuffering_stream_complete;
stream->abort = msg_rebuffering_stream_abort;
stream->put_block = msg_rebuffering_stream_write_chunk;
stream->is_write_ready = msg_rebuffering_stream_write_ready;
stream->data_object = sd;
stream->window_id = context;
return stream;
}

Просмотреть файл

@ -1,299 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "mimeobj.h"
#include "prmem.h"
#include "plstr.h"
/* Way to destroy any notions of modularity or class hierarchy, Terry! */
# include "mimetpla.h"
# include "mimethtm.h"
# include "mimecont.h"
MimeDefClass (MimeObject, MimeObjectClass, mimeObjectClass, NULL);
static int MimeObject_initialize (MimeObject *);
static void MimeObject_finalize (MimeObject *);
static int MimeObject_parse_begin (MimeObject *);
static int MimeObject_parse_buffer (char *, PRInt32, MimeObject *);
static int MimeObject_parse_line (char *, PRInt32, MimeObject *);
static int MimeObject_parse_eof (MimeObject *, PRBool);
static int MimeObject_parse_end (MimeObject *, PRBool);
static PRBool MimeObject_displayable_inline_p (MimeObjectClass *class,
MimeHeaders *hdrs);
#if defined(DEBUG) && defined(XP_UNIX)
static int MimeObject_debug_print (MimeObject *, FILE *, PRInt32 depth);
#endif
static int
MimeObjectClassInitialize(MimeObjectClass *class)
{
PR_ASSERT(!class->class_initialized);
class->initialize = MimeObject_initialize;
class->finalize = MimeObject_finalize;
class->parse_begin = MimeObject_parse_begin;
class->parse_buffer = MimeObject_parse_buffer;
class->parse_line = MimeObject_parse_line;
class->parse_eof = MimeObject_parse_eof;
class->parse_end = MimeObject_parse_end;
class->displayable_inline_p = MimeObject_displayable_inline_p;
#if defined(DEBUG) && defined(XP_UNIX)
class->debug_print = MimeObject_debug_print;
#endif
return 0;
}
static int
MimeObject_initialize (MimeObject *obj)
{
/* This is an abstract class; it shouldn't be directly instanciated. */
PR_ASSERT(obj->class != &mimeObjectClass);
/* Set up the content-type and encoding. */
if (!obj->content_type && obj->headers)
obj->content_type = MimeHeaders_get (obj->headers, HEADER_CONTENT_TYPE,
PR_TRUE, PR_FALSE);
if (!obj->encoding && obj->headers)
obj->encoding = MimeHeaders_get (obj->headers,
HEADER_CONTENT_TRANSFER_ENCODING,
PR_TRUE, PR_FALSE);
/* Special case to normalize some types and encodings to a canonical form.
(These are nonstandard types/encodings which have been seen to appear in
multiple forms; we normalize them so that things like looking up icons
and extensions has consistent behavior for the receiver, regardless of
the "alias" type that the sender used.)
*/
if (!obj->content_type)
;
else if (!PL_strcasecmp(obj->content_type, APPLICATION_UUENCODE2) ||
!PL_strcasecmp(obj->content_type, APPLICATION_UUENCODE3) ||
!PL_strcasecmp(obj->content_type, APPLICATION_UUENCODE4))
{
PR_Free(obj->content_type);
obj->content_type = PL_strdup(APPLICATION_UUENCODE);
}
else if (!PL_strcasecmp(obj->content_type, IMAGE_XBM2) ||
!PL_strcasecmp(obj->content_type, IMAGE_XBM3))
{
PR_Free(obj->content_type);
obj->content_type = PL_strdup(IMAGE_XBM);
}
if (!obj->encoding)
;
else if (!PL_strcasecmp(obj->encoding, ENCODING_UUENCODE2) ||
!PL_strcasecmp(obj->encoding, ENCODING_UUENCODE3) ||
!PL_strcasecmp(obj->encoding, ENCODING_UUENCODE4))
{
PR_Free(obj->encoding);
obj->encoding = PL_strdup(ENCODING_UUENCODE);
}
else if (!PL_strcasecmp(obj->encoding, ENCODING_COMPRESS2))
{
PR_Free(obj->encoding);
obj->encoding = PL_strdup(ENCODING_COMPRESS);
}
else if (!PL_strcasecmp(obj->encoding, ENCODING_GZIP2))
{
PR_Free(obj->encoding);
obj->encoding = PL_strdup(ENCODING_GZIP);
}
return 0;
}
static void
MimeObject_finalize (MimeObject *obj)
{
obj->class->parse_eof (obj, PR_FALSE);
obj->class->parse_end (obj, PR_FALSE);
if (obj->headers)
{
MimeHeaders_free(obj->headers);
obj->headers = 0;
}
/* Should have been freed by parse_eof, but just in case... */
PR_ASSERT(!obj->ibuffer);
PR_ASSERT(!obj->obuffer);
PR_FREEIF (obj->ibuffer);
PR_FREEIF (obj->obuffer);
PR_FREEIF(obj->content_type);
PR_FREEIF(obj->encoding);
if (obj->options && obj->options->state)
{
PR_Free(obj->options->state);
obj->options->state = 0;
}
}
static int
MimeObject_parse_begin (MimeObject *obj)
{
PR_ASSERT (!obj->closed_p);
/* If we haven't set up the state object yet, then this should be
the outermost object... */
if (obj->options && !obj->options->state)
{
PR_ASSERT(!obj->headers); /* should be the outermost object. */
obj->options->state = PR_NEW(MimeParseStateObject);
if (!obj->options->state) return MK_OUT_OF_MEMORY;
memset(obj->options->state, 0, sizeof(*obj->options->state));
obj->options->state->root = obj;
obj->options->state->separator_suppressed_p = PR_TRUE; /* no first sep */
}
/* Decide whether this object should be output or not... */
if (!obj->options || !obj->options->output_fn)
obj->output_p = PR_FALSE;
else if (!obj->options->part_to_load)
obj->output_p = PR_TRUE;
else
{
char *id = mime_part_address(obj);
if (!id) return MK_OUT_OF_MEMORY;
obj->output_p = !PL_strcmp(id, obj->options->part_to_load);
PR_Free(id);
}
/* Way to destroy any notions of modularity or class hierarchy, Terry! */
if (obj->options && obj->options->nice_html_only_p) {
if (!mime_subclass_p(obj->class,
(MimeObjectClass*) &mimeInlineTextHTMLClass) &&
!mime_subclass_p(obj->class,
(MimeObjectClass*) &mimeInlineTextPlainClass) &&
!mime_subclass_p(obj->class,
(MimeObjectClass*) &mimeContainerClass)) {
obj->output_p = PR_FALSE;
}
}
return 0;
}
static int
MimeObject_parse_buffer (char *buffer, PRInt32 size, MimeObject *obj)
{
PR_ASSERT(!obj->closed_p);
if (obj->closed_p) return -1;
return msg_LineBuffer (buffer, size,
&obj->ibuffer, &obj->ibuffer_size, &obj->ibuffer_fp,
PR_TRUE,
((int (*) (char *, PRInt32, void *))
/* This cast is to turn void into MimeObject */
obj->class->parse_line),
obj);
}
static int
MimeObject_parse_line (char *line, PRInt32 length, MimeObject *obj)
{
/* This method should never be called. */
PR_ASSERT(0);
return -1;
}
static int
MimeObject_parse_eof (MimeObject *obj, PRBool abort_p)
{
if (obj->closed_p) return 0;
PR_ASSERT(!obj->parsed_p);
/* If there is still data in the ibuffer, that means that the last line of
this part didn't end in a newline; so push it out anyway (this means that
the parse_line method will be called with a string with no trailing
newline, which isn't the usual case.)
*/
if (!abort_p &&
obj->ibuffer_fp > 0)
{
int status = obj->class->parse_line (obj->ibuffer, obj->ibuffer_fp, obj);
obj->ibuffer_fp = 0;
if (status < 0)
{
obj->closed_p = PR_TRUE;
return status;
}
}
obj->closed_p = PR_TRUE;
return 0;
}
static int
MimeObject_parse_end (MimeObject *obj, PRBool abort_p)
{
if (obj->parsed_p)
{
PR_ASSERT(obj->closed_p);
return 0;
}
/* We won't be needing these buffers any more; nuke 'em. */
PR_FREEIF(obj->ibuffer);
obj->ibuffer_fp = 0;
obj->ibuffer_size = 0;
PR_FREEIF(obj->obuffer);
obj->obuffer_fp = 0;
obj->obuffer_size = 0;
obj->parsed_p = PR_TRUE;
return 0;
}
static PRBool
MimeObject_displayable_inline_p (MimeObjectClass *class, MimeHeaders *hdrs)
{
PR_ASSERT(0); /* This method should never be called. */
return PR_FALSE;
}
#if defined(DEBUG) && defined(XP_UNIX)
static int
MimeObject_debug_print (MimeObject *obj, FILE *stream, PRInt32 depth)
{
int i;
char *addr = mime_part_address(obj);
for (i=0; i < depth; i++)
fprintf(stream, " ");
fprintf(stream, "<%s %s 0x%08X>\n", obj->class->class_name,
addr ? addr : "???",
(PRUint32) obj);
PR_FREEIF(addr);
return 0;
}
#endif

Просмотреть файл

@ -188,7 +188,7 @@ struct MimeObject {
#define MimeObject_grow_obuffer(obj, desired_size) \
(((desired_size) >= (obj)->obuffer_size) ? \
msg_GrowBuffer ((desired_size), sizeof(char), 1024, \
mime_GrowBuffer ((desired_size), sizeof(char), 1024, \
&(obj)->obuffer, &(obj)->obuffer_size) \
: 0)

Просмотреть файл

@ -1,305 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "mimetext.h"
#include "libi18n.h"
#include "prmem.h"
#include "plstr.h"
#define MIME_SUPERCLASS mimeLeafClass
MimeDefClass(MimeInlineText, MimeInlineTextClass, mimeInlineTextClass,
&MIME_SUPERCLASS);
static int MimeInlineText_initialize (MimeObject *);
static void MimeInlineText_finalize (MimeObject *);
static int MimeInlineText_rot13_line (MimeObject *, char *line, PRInt32 length);
static int MimeInlineText_parse_eof (MimeObject *obj, PRBool abort_p);
static int MimeInlineText_parse_end (MimeObject *, PRBool);
static int MimeInlineText_parse_decoded_buffer (char *, PRInt32, MimeObject *);
static int MimeInlineText_rotate_convert_and_parse_line(char *, PRInt32,
MimeObject *);
static int
MimeInlineTextClassInitialize(MimeInlineTextClass *class)
{
MimeObjectClass *oclass = (MimeObjectClass *) class;
MimeLeafClass *lclass = (MimeLeafClass *) class;
PR_ASSERT(!oclass->class_initialized);
oclass->initialize = MimeInlineText_initialize;
oclass->finalize = MimeInlineText_finalize;
oclass->parse_eof = MimeInlineText_parse_eof;
oclass->parse_end = MimeInlineText_parse_end;
class->rot13_line = MimeInlineText_rot13_line;
lclass->parse_decoded_buffer = MimeInlineText_parse_decoded_buffer;
return 0;
}
static int
MimeInlineText_initialize (MimeObject *obj)
{
MimeInlineText *text = (MimeInlineText *) obj;
/* This is an abstract class; it shouldn't be directly instanciated. */
PR_ASSERT(obj->class != (MimeObjectClass *) &mimeInlineTextClass);
/* Figure out an appropriate charset for this object.
*/
if (!text->charset && obj->headers)
{
if (obj->options && obj->options->override_charset)
{
text->charset = PL_strdup(obj->options->override_charset);
}
else
{
char *ct = MimeHeaders_get (obj->headers, HEADER_CONTENT_TYPE,
PR_FALSE, PR_FALSE);
if (ct)
{
text->charset = MimeHeaders_get_parameter (ct, "charset", NULL, NULL);
PR_Free(ct);
}
if (!text->charset)
{
/* If we didn't find "Content-Type: ...; charset=XX" then look
for "X-Sun-Charset: XX" instead. (Maybe this should be done
in MimeSunAttachmentClass, but it's harder there than here.)
*/
text->charset = MimeHeaders_get (obj->headers,
HEADER_X_SUN_CHARSET,
PR_FALSE, PR_FALSE);
}
if (!text->charset)
{
if (obj->options && obj->options->default_charset)
text->charset = PL_strdup(obj->options->default_charset);
/* Do not label US-ASCII if the app default charset is multibyte.
Perhaps US-ASCII label should be removed for all cases.
*/
else if (MULTIBYTE & INTL_DefaultDocCharSetID(0))
;
else
text->charset = PL_strdup("US-ASCII");
}
}
}
return ((MimeObjectClass*)&MIME_SUPERCLASS)->initialize(obj);
}
static void
MimeInlineText_finalize (MimeObject *obj)
{
MimeInlineText *text = (MimeInlineText *) obj;
obj->class->parse_eof (obj, PR_FALSE);
obj->class->parse_end (obj, PR_FALSE);
PR_FREEIF(text->charset);
/* Should have been freed by parse_eof, but just in case... */
PR_ASSERT(!text->cbuffer);
PR_FREEIF (text->cbuffer);
((MimeObjectClass*)&MIME_SUPERCLASS)->finalize (obj);
}
static int
MimeInlineText_parse_eof (MimeObject *obj, PRBool abort_p)
{
if (obj->closed_p) return 0;
PR_ASSERT(!obj->parsed_p);
/* If there is still data in the ibuffer, that means that the last line of
this part didn't end in a newline; so push it out anyway (this means that
the parse_line method will be called with a string with no trailing
newline, which isn't the usual case.) We do this here, rather than in
MimeObject_parse_eof, because MimeObject likes to shove things through
parse_line, and we have to shove it through the magic rotating-and-converting
code. So, we do that and digest the buffer before MimeObject has a chance
to do the wrong thing. See bug #26276 for more painful details.
*/
if (!abort_p &&
obj->ibuffer_fp > 0)
{
int status = MimeInlineText_rotate_convert_and_parse_line (obj->ibuffer,
obj->ibuffer_fp,
obj);
obj->ibuffer_fp = 0;
if (status < 0)
{
obj->closed_p = PR_TRUE;
return status;
}
}
return ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_eof (obj, abort_p);
}
static int
MimeInlineText_parse_end (MimeObject *obj, PRBool abort_p)
{
MimeInlineText *text = (MimeInlineText *) obj;
if (obj->parsed_p)
{
PR_ASSERT(obj->closed_p);
return 0;
}
/* We won't be needing this buffer any more; nuke it. */
PR_FREEIF(text->cbuffer);
text->cbuffer_size = 0;
return ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_end (obj, abort_p);
}
/* This maps A-M to N-Z and N-Z to A-M. All other characters are left alone.
(Comments in GNUS imply that for Japanese, one should rotate by 47?)
*/
static const unsigned char MimeInlineText_rot13_table[256] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
59, 60, 61, 62, 63, 64, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 91, 92, 93, 94, 95, 96,
110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 97, 98,
99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 123, 124, 125, 126,
127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156,
157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171,
172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186,
187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201,
202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216,
217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231,
232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246,
247, 248, 249, 250, 251, 252, 253, 254, 255 };
static int
MimeInlineText_rot13_line (MimeObject *obj, char *line, PRInt32 length)
{
unsigned char *s, *end;
PR_ASSERT(line);
if (!line) return -1;
s = (unsigned char *) line;
end = s + length;
while (s < end)
{
*s = MimeInlineText_rot13_table[*s];
s++;
}
return 0;
}
static int
MimeInlineText_parse_decoded_buffer (char *buf, PRInt32 size, MimeObject *obj)
{
PR_ASSERT(!obj->closed_p);
if (obj->closed_p) return -1;
/* MimeLeaf takes care of this. */
PR_ASSERT(obj->output_p && obj->options && obj->options->output_fn);
if (!obj->options) return -1;
/* If we're supposed to write this object, but aren't supposed to convert
it to HTML, simply pass it through unaltered. */
if (!obj->options->write_html_p)
return MimeObject_write(obj, buf, size, PR_TRUE);
/* This is just like the parse_decoded_buffer method we inherit from the
MimeLeaf class, except that we line-buffer to our own wrapper on the
`parse_line' method instead of calling the `parse_line' method directly.
*/
return msg_LineBuffer (buf, size,
&obj->ibuffer, &obj->ibuffer_size, &obj->ibuffer_fp,
PR_TRUE,
((int (*) (char *, PRInt32, void *))
/* This cast is to turn void into MimeObject */
MimeInlineText_rotate_convert_and_parse_line),
obj);
}
#define MimeInlineText_grow_cbuffer(text, desired_size) \
(((desired_size) >= (text)->cbuffer_size) ? \
msg_GrowBuffer ((desired_size), sizeof(char), 100, \
&(text)->cbuffer, &(text)->cbuffer_size) \
: 0)
static int
MimeInlineText_rotate_convert_and_parse_line(char *line, PRInt32 length,
MimeObject *obj)
{
int status;
MimeInlineText *text = (MimeInlineText *) obj;
MimeInlineTextClass *textc = (MimeInlineTextClass *) obj->class;
char *converted = 0;
PR_ASSERT(!obj->closed_p);
if (obj->closed_p) return -1;
/* Rotate the line, if desired (this happens on the raw data, before any
charset conversion.) */
if (obj->options && obj->options->rot13_p)
{
status = textc->rot13_line(obj, line, length);
if (status < 0) return status;
}
/* Now convert to the canonical charset, if desired.
*/
if (obj->options && obj->options->charset_conversion_fn)
{
PRInt32 converted_len = 0;
const char *output_charset = (obj->options->override_charset
? obj->options->override_charset
: obj->options->default_charset);
status = obj->options->charset_conversion_fn(line, length,
text->charset,
output_charset,
&converted,
&converted_len,
obj->options->stream_closure);
if (status < 0)
{
PR_FREEIF(converted);
return status;
}
if (converted)
{
line = converted;
length = converted_len;
}
}
/* Now that the line has been converted, call the subclass's parse_line
method with the decoded data. */
status = obj->class->parse_line(line, length, obj);
PR_FREEIF(converted);
return status;
}

Просмотреть файл

@ -1,135 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "mimetpla.h"
#include "prmem.h"
#include "plstr.h"
#define MIME_SUPERCLASS mimeInlineTextClass
MimeDefClass(MimeInlineTextPlain, MimeInlineTextPlainClass,
mimeInlineTextPlainClass, &MIME_SUPERCLASS);
static int MimeInlineTextPlain_parse_begin (MimeObject *);
static int MimeInlineTextPlain_parse_line (char *, PRInt32, MimeObject *);
static int MimeInlineTextPlain_parse_eof (MimeObject *, PRBool);
static int
MimeInlineTextPlainClassInitialize(MimeInlineTextPlainClass *class)
{
MimeObjectClass *oclass = (MimeObjectClass *) class;
PR_ASSERT(!oclass->class_initialized);
oclass->parse_begin = MimeInlineTextPlain_parse_begin;
oclass->parse_line = MimeInlineTextPlain_parse_line;
oclass->parse_eof = MimeInlineTextPlain_parse_eof;
return 0;
}
static int
MimeInlineTextPlain_parse_begin (MimeObject *obj)
{
int status = 0;
status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_begin(obj);
if (status < 0) return status;
if (!obj->output_p) return 0;
if (obj->options &&
obj->options->write_html_p &&
obj->options->output_fn)
{
char* strs[4];
char* s;
strs[0] = "<PRE>";
strs[1] = "<PRE VARIABLE>";
strs[2] = "<PRE WRAP>";
strs[3] = "<PRE VARIABLE WRAP>";
s = PL_strdup(strs[(obj->options->variable_width_plaintext_p ? 1 : 0) +
(obj->options->wrap_long_lines_p ? 2 : 0)]);
if (!s) return MK_OUT_OF_MEMORY;
status = MimeObject_write(obj, s, PL_strlen(s), PR_FALSE);
PR_Free(s);
if (status < 0) return status;
/* text/plain objects always have separators before and after them.
Note that this is not the case for text/enriched objects. */
status = MimeObject_write_separator(obj);
if (status < 0) return status;
}
return 0;
}
static int
MimeInlineTextPlain_parse_eof (MimeObject *obj, PRBool abort_p)
{
int status;
if (obj->closed_p) return 0;
/* Run parent method first, to flush out any buffered data. */
status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_eof(obj, abort_p);
if (status < 0) return status;
if (!obj->output_p) return 0;
if (obj->options &&
obj->options->write_html_p &&
obj->options->output_fn &&
!abort_p)
{
char s[] = "</PRE>";
status = MimeObject_write(obj, s, PL_strlen(s), PR_FALSE);
if (status < 0) return status;
/* text/plain objects always have separators before and after them.
Note that this is not the case for text/enriched objects.
*/
status = MimeObject_write_separator(obj);
if (status < 0) return status;
}
return 0;
}
static int
MimeInlineTextPlain_parse_line (char *line, PRInt32 length, MimeObject *obj)
{
int status;
PR_ASSERT(length > 0);
if (length <= 0) return 0;
status = MimeObject_grow_obuffer (obj, length * 2 + 40);
if (status < 0) return status;
/* Copy `line' to `out', quoting HTML along the way.
Note: this function does no charset conversion; that has already
been done.
*/
*obj->obuffer = 0;
status = NET_ScanForURLs (
(obj->options ? obj->options->pane : 0),
line, length, obj->obuffer, obj->obuffer_size - 10,
(obj->options ?
obj->options->dont_touch_citations_p : PR_FALSE));
if (status < 0) return status;
PR_ASSERT(*line == 0 || *obj->obuffer);
return MimeObject_write(obj, obj->obuffer, PL_strlen(obj->obuffer), PR_TRUE);
}

Просмотреть файл

@ -1,357 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "mimetric.h"
#include "prmem.h"
#include "plstr.h"
#define MIME_SUPERCLASS mimeInlineTextClass
MimeDefClass(MimeInlineTextRichtext, MimeInlineTextRichtextClass,
mimeInlineTextRichtextClass, &MIME_SUPERCLASS);
static int MimeInlineTextRichtext_parse_line (char *, PRInt32, MimeObject *);
static int MimeInlineTextRichtext_parse_begin (MimeObject *);
static int MimeInlineTextRichtext_parse_eof (MimeObject *, PRBool);
static int
MimeInlineTextRichtextClassInitialize(MimeInlineTextRichtextClass *class)
{
MimeObjectClass *oclass = (MimeObjectClass *) class;
PR_ASSERT(!oclass->class_initialized);
oclass->parse_begin = MimeInlineTextRichtext_parse_begin;
oclass->parse_line = MimeInlineTextRichtext_parse_line;
oclass->parse_eof = MimeInlineTextRichtext_parse_eof;
return 0;
}
/* This function has this clunky interface because it needs to be called
from outside this module (no MimeObject, etc.)
*/
int
MimeRichtextConvert (char *line, PRInt32 length,
int (*output_fn) (char *buf, PRInt32 size, void *closure),
void *closure,
char **obufferP,
PRInt32 *obuffer_sizeP,
PRBool enriched_p)
{
/* 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;
int desired_size;
desired_size = length * 4;
if (desired_size >= *obuffer_sizeP)
status = msg_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 (!XP_IS_SPACE (*this_start)) break;
if (this_start >= line + length) /* blank line */
{
PL_strcpy (*obufferP, "<BR>");
return output_fn (*obufferP, PL_strlen(*obufferP), closure);
}
}
out = *obufferP;
*out = 0;
data_end = line + length;
last_end = line;
this_start = last_end;
this_end = this_start;
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 &&
!XP_IS_SPACE (*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)
{
XP_MEMCPY (out, last_end, this_start - last_end);
out += this_start - last_end;
*out = 0;
}
if (this_start >= data_end)
break;
else if (*this_start == '&')
{
PL_strcpy (out, "&amp;"); out += PL_strlen (out);
}
else if (*this_start == '>')
{
PL_strcpy (out, "&gt;"); out += PL_strlen (out);
}
else if (enriched_p &&
this_start < data_end + 1 &&
this_start[0] == '<' &&
this_start[1] == '<')
{
PL_strcpy (out, "&lt;"); out += PL_strlen (out);
}
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 (!PL_strncasecmp ("BIGGER>", old, 7))
tag_open = "<FONT SIZE=\"+1\">", tag_close = "</FONT>";
else if (!PL_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 (!PL_strncasecmp ("BOLD>", old, 5))
tag_open = "<B>", tag_close = "</B>";
break;
case 'c': case 'C':
if (!PL_strncasecmp ("CENTER>", old, 7))
tag_open = "<CENTER>", tag_close = "</CENTER>";
else if (!enriched_p &&
!PL_strncasecmp ("COMMENT>", old, 8))
tag_open = "<!-- ", tag_close = " -->";
break;
case 'e': case 'E':
if (!PL_strncasecmp ("EXCERPT>", old, 8))
tag_open = "<BLOCKQUOTE>", tag_close = "</BLOCKQUOTE>";
break;
case 'f': case 'F':
if (!PL_strncasecmp ("FIXED>", old, 6))
tag_open = "<TT>", tag_close = "</TT>";
else if (enriched_p &&
!PL_strncasecmp ("FLUSHBOTH>", old, 10))
tag_open = "<P ALIGN=LEFT>", tag_close = "</P>";
else if (!PL_strncasecmp ("FLUSHLEFT>", old, 10))
tag_open = "<P ALIGN=LEFT>", tag_close = "</P>";
else if (!PL_strncasecmp ("FLUSHRIGHT>", old, 11))
tag_open = "<P ALIGN=RIGHT>", tag_close = "</P>";
else if (!enriched_p &&
!PL_strncasecmp ("FOOTING>", old, 8))
tag_open = "<H6>", tag_close = "</H6>";
break;
case 'h': case 'H':
if (!enriched_p &&
!PL_strncasecmp ("HEADING>", old, 8))
tag_open = "<H6>", tag_close = "</H6>";
break;
case 'i': case 'I':
if (!PL_strncasecmp ("INDENT>", old, 7))
tag_open = "<UL>", tag_close = "</UL>";
else if (!PL_strncasecmp ("INDENTRIGHT>", old, 12))
tag_open = 0, tag_close = 0;
/* else if (!enriched_p &&
!PL_strncasecmp ("ISO-8859-", old, 9))
tag_open = 0, tag_close = 0; */
else if (!PL_strncasecmp ("ITALIC>", old, 7))
tag_open = "<I>", tag_close = "</I>";
break;
case 'l': case 'L':
if (!enriched_p &&
!PL_strncasecmp ("LT>", old, 3))
tag_open = "&lt;", tag_close = 0;
break;
case 'n': case 'N':
if (!enriched_p &&
!PL_strncasecmp ("NL>", old, 3))
tag_open = "<BR>", tag_close = 0;
if (enriched_p &&
!PL_strncasecmp ("NOFILL>", old, 7))
tag_open = "<NOBR>", tag_close = "</NOBR>";
/* else if (!enriched_p &&
!PL_strncasecmp ("NO-OP>", old, 6))
tag_open = 0, tag_close = 0; */
/* else if (!enriched_p &&
!PL_strncasecmp ("NP>", old, 3))
tag_open = 0, tag_close = 0; */
break;
case 'o': case 'O':
if (!enriched_p &&
!PL_strncasecmp ("OUTDENT>", old, 8))
tag_open = 0, tag_close = 0;
else if (!enriched_p &&
!PL_strncasecmp ("OUTDENTRIGHT>", old, 13))
tag_open = 0, tag_close = 0;
break;
case 'p': case 'P':
if (enriched_p &&
!PL_strncasecmp ("PARAM>", old, 6))
tag_open = "<!-- ", tag_close = " -->";
else if (!enriched_p &&
!PL_strncasecmp ("PARAGRAPH>", old, 10))
tag_open = "<P>", tag_close = 0;
break;
case 's': case 'S':
if (!enriched_p &&
!PL_strncasecmp ("SAMEPAGE>", old, 9))
tag_open = 0, tag_close = 0;
else if (!enriched_p &&
!PL_strncasecmp ("SIGNATURE>", old, 10))
tag_open = "<I><FONT SIZE=\"-1\">", tag_close = "</FONT></I>";
else if (!PL_strncasecmp ("SMALLER>", old, 8))
tag_open = "<FONT SIZE=\"-1\">", tag_close = "</FONT>";
else if (!enriched_p &&
!PL_strncasecmp ("SUBSCRIPT>", old, 10))
tag_open = "<SUB>", tag_close = "</SUB>";
else if (!enriched_p &&
!PL_strncasecmp ("SUPERSCRIPT>", old, 12))
tag_open = "<SUP>", tag_close = "</SUP>";
break;
case 'u': case 'U':
if (!PL_strncasecmp ("UNDERLINE>", old, 10))
tag_open = "<U>", tag_close = "</U>";
/* else if (!enriched_p &&
!PL_strncasecmp ("US-ASCII>", old, 10))
tag_open = 0, tag_close = 0; */
break;
case 'v': case 'V':
if (enriched_p &&
!PL_strncasecmp ("VERBATIM>", old, 9))
tag_open = "<PRE>", tag_close = "</PRE>";
break;
}
if (this_start[1] == '/')
{
if (tag_close) PL_strcpy (out, tag_close);
out += PL_strlen (out);
}
else
{
if (tag_open) PL_strcpy (out, tag_open);
out += PL_strlen (out);
}
}
/* now go around again */
last_end = this_end;
this_start = last_end;
}
*out = 0;
return output_fn (*obufferP, out - *obufferP, closure);
}
static int
MimeInlineTextRichtext_parse_line (char *line, PRInt32 length, MimeObject *obj)
{
PRBool enriched_p = (((MimeInlineTextRichtextClass *) obj->class)
->enriched_p);
return MimeRichtextConvert (line, length,
obj->options->output_fn,
obj->options->stream_closure,
&obj->obuffer, &obj->obuffer_size,
enriched_p);
}
static int
MimeInlineTextRichtext_parse_begin (MimeObject *obj)
{
int status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_begin(obj);
char s[] = "";
if (status < 0) return status;
return MimeObject_write(obj, s, 0, PR_TRUE); /* force out any separators... */
}
/* This method is largely the same as that of MimeInlineTextHTML; maybe that
means that MimeInlineTextRichtext and MimeInlineTextEnriched should share
a common parent with it which is not also shared by MimeInlineTextPlain?
*/
static int
MimeInlineTextRichtext_parse_eof (MimeObject *obj, PRBool abort_p)
{
int status;
if (obj->closed_p) return 0;
/* Run parent method first, to flush out any buffered data. */
status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_eof(obj, abort_p);
if (status < 0) return status;
if (obj->options &&
obj->options->write_html_p &&
obj->options->set_html_state_fn)
{
return obj->options->set_html_state_fn(obj->options->stream_closure,
PR_FALSE, /* layer_encapulate_p */
PR_FALSE, /* start_p */
abort_p);
}
return 0;
}

Просмотреть файл

@ -1,177 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
msg.h --- internal defs for the msg library
*/
#ifndef _MSG_H_
#define _MSG_H_
#include "xp.h"
#include "msgcom.h"
#include "msgnet.h"
#include "msgutils.h"
#include "xpgetstr.h"
#ifdef XP_CPLUSPLUS
class MessageDBView;
class MSG_SendPart;
#endif
#define MANGLE_INTERNAL_ENVELOPE_LINES /* We always need to do this, for now */
#undef FIXED_SEPARATORS /* this doesn't work yet */
#define EMIT_CONTENT_LENGTH /* Experimental; and anyway, we only
emit it, we don't parse it, so this
is only the first step. */
/* hack - this string gets appended to the beginning of an attachment field
during a forward quoted operation */
#define MSG_FORWARD_COOKIE "$forward_quoted$"
/* The PRINTF macro is for debugging messages of unusual events (summary */
/* files out of date or invalid or the like. It's so that as I use the mail */
/* to actually read my e-mail, I can look at the shell output whenever */
/* something unusual happens so I can get some clues as to what's going on. */
/* Please don't remove any PRINTF calls you see, and be sparing of adding */
/* any additional ones. Thanks. - Terry */
#ifdef DEBUG
#define PRINTF(msg) PR_LogPrint msg
#else
#define PRINTF(msg)
#endif
/* The Netscape-specific header fields that we use for storing our
various bits of state in mail folders.
*/
#define X_MOZILLA_STATUS "X-Mozilla-Status"
#define X_MOZILLA_STATUS_FORMAT X_MOZILLA_STATUS ": %04.4x"
#define X_MOZILLA_STATUS_LEN /*1234567890123456*/ 16
#define X_MOZILLA_STATUS2 "X-Mozilla-Status2"
#define X_MOZILLA_STATUS2_FORMAT X_MOZILLA_STATUS2 ": %08.8x"
#define X_MOZILLA_STATUS2_LEN /*12345678901234567*/ 17
#define X_MOZILLA_DRAFT_INFO "X-Mozilla-Draft-Info"
#define X_MOZILLA_DRAFT_INFO_LEN /*12345678901234567890*/ 20
#define X_MOZILLA_NEWSHOST "X-Mozilla-News-Host"
#define X_MOZILLA_NEWSHOST_LEN /*1234567890123456789*/ 19
#define X_UIDL "X-UIDL"
#define X_UIDL_LEN /*123456*/ 6
#define CONTENT_LENGTH "Content-Length"
#define CONTENT_LENGTH_LEN /*12345678901234*/ 14
/* Provide a common means of detecting empty lines in a message. i.e. to detect the end of headers among other things...*/
#define EMPTY_MESSAGE_LINE(buf) (buf[0] == CR || buf[0] == LF || buf[0] == '\0')
typedef PRInt32 MsgChangeCookie; /* used to unregister change notification */
/* The three ways the list of newsgroups can be pruned.
*/
typedef enum
{
MSG_ShowAll,
MSG_ShowSubscribed,
MSG_ShowSubscribedWithArticles
} MSG_NEWSGROUP_DISPLAY_STYLE;
/* The three ways to deliver a message.
*/
typedef enum
{
MSG_DeliverNow,
MSG_QueueForLater,
MSG_SaveAs,
MSG_SaveAsDraft,
MSG_SaveAsTemplate
} MSG_Deliver_Mode;
/* A little enum for things we'd like to learn lazily.
* e.g. displaying recipients for this pane? Yes we are,
* no we're not, haven't figured it out yet
*/
typedef enum
{
msg_No,
msg_Yes,
msg_DontKnow
} msg_YesNoDontKnow;
/* The MSG_REPLY_TYPE shares the same space as MSG_CommandType, to avoid
possible weird errors, but is restricted to the `composition' commands
(MSG_ReplyToSender through MSG_ForwardMessage.)
*/
typedef MSG_CommandType MSG_REPLY_TYPE;
/* The list of all message flags to not write to disk. */
#define MSG_FLAG_RUNTIME_ONLY (MSG_FLAG_ELIDED)
/* ===========================================================================
Structures.
===========================================================================
*/
/* Used for the various things that parse RFC822 headers...
*/
typedef struct message_header
{
const char *value; /* The contents of a header (after ": ") */
PRInt32 length; /* The length of the data (it is not NULL-terminated.) */
} message_header;
XP_BEGIN_PROTOS
/* we'll need this for localized folder names */
extern int MK_MSG_INBOX_L10N_NAME;
extern int MK_MSG_OUTBOX_L10N_NAME; /* win16 variations are in allxpstr.h */
extern int MK_MSG_OUTBOX_L10N_NAME_OLD;
extern int MK_MSG_TRASH_L10N_NAME;
extern int MK_MSG_DRAFTS_L10N_NAME;
extern int MK_MSG_SENT_L10N_NAME;
extern int MK_MSG_TEMPLATES_L10N_NAME;
#define INBOX_FOLDER_NAME MSG_GetSpecialFolderName(MK_MSG_INBOX_L10N_NAME)
#define QUEUE_FOLDER_NAME MSG_GetSpecialFolderName(MK_MSG_OUTBOX_L10N_NAME)
#define QUEUE_FOLDER_NAME_OLD MSG_GetSpecialFolderName(MK_MSG_OUTBOX_L10N_NAME_OLD)
#define TRASH_FOLDER_NAME MSG_GetSpecialFolderName(MK_MSG_TRASH_L10N_NAME)
#define DRAFTS_FOLDER_NAME MSG_GetSpecialFolderName(MK_MSG_DRAFTS_L10N_NAME)
#define SENT_FOLDER_NAME MSG_GetSpecialFolderName(MK_MSG_SENT_L10N_NAME)
#define TEMPLATES_FOLDER_NAME MSG_GetSpecialFolderName(MK_MSG_TEMPLATES_L10N_NAME)
#ifdef XP_OS2
#define INBOX_FOLDER_PRETTY_NAME MSG_GetSpecialFolderPrettyName(MK_MSG_INBOX_L10N_NAME)
#define QUEUE_FOLDER_PRETTY_NAME MSG_GetSpecialFolderPrettyName(MK_MSG_OUTBOX_L10N_NAME)
#define QUEUE_FOLDER_PRETTY_NAME_OLD MSG_GetSpecialFolderPrettyName(MK_MSG_OUTBOX_L10N_NAME_OLD)
#define TRASH_FOLDER_PRETTY_NAME MSG_GetSpecialFolderPrettyName(MK_MSG_TRASH_L10N_NAME)
#define DRAFTS_FOLDER_PRETTY_NAME MSG_GetSpecialFolderPrettyName(MK_MSG_DRAFTS_L10N_NAME)
#define SENT_FOLDER_PRETTY_NAME MSG_GetSpecialFolderPrettyName(MK_MSG_SENT_L10N_NAME)
#define TEMPLATES_FOLDER_PRETTY_NAME MSG_GetSpecialFolderPrettyName(MK_MSG_TEMPLATES_L10N_NAME)
#endif
XP_END_PROTOS
#endif /* !_MSG_H_ */