зеркало из https://github.com/mozilla/pjs.git
More cleanup for modular libmime.
This commit is contained in:
Родитель
30fd516d31
Коммит
6fb30ce75f
|
@ -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, "&"); out += PL_strlen (out);
|
||||
}
|
||||
else if (*this_start == '>')
|
||||
{
|
||||
PL_strcpy (out, ">"); out += PL_strlen (out);
|
||||
}
|
||||
else if (enriched_p &&
|
||||
this_start < data_end + 1 &&
|
||||
this_start[0] == '<' &&
|
||||
this_start[1] == '<')
|
||||
{
|
||||
PL_strcpy (out, "<"); 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 = "<", 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_ */
|
Загрузка…
Ссылка в новой задаче