home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / libmime / mimeobj.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  8.6 KB  |  305 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. /* mimeobj.c --- definition of the MimeObject class (see mimei.h)
  20.    Created: Jamie Zawinski <jwz@netscape.com>, 15-May-96.
  21.  */
  22.  
  23. #include "mimeobj.h"
  24.  
  25. #ifndef MOZILLA_30
  26. /* Way to destroy any notions of modularity or class hierarchy, Terry! */
  27. # include "mimetpla.h"
  28. # include "mimethtm.h"
  29. # include "mimecont.h"
  30. #endif /* !MOZILLA_30 */
  31.  
  32. MimeDefClass (MimeObject, MimeObjectClass, mimeObjectClass, NULL);
  33.  
  34. static int MimeObject_initialize (MimeObject *);
  35. static void MimeObject_finalize (MimeObject *);
  36. static int MimeObject_parse_begin (MimeObject *);
  37. static int MimeObject_parse_buffer (char *, int32, MimeObject *);
  38. static int MimeObject_parse_line (char *, int32, MimeObject *);
  39. static int MimeObject_parse_eof (MimeObject *, XP_Bool);
  40. static int MimeObject_parse_end (MimeObject *, XP_Bool);
  41. static XP_Bool MimeObject_displayable_inline_p (MimeObjectClass *class,
  42.                                                 MimeHeaders *hdrs);
  43.  
  44. #if defined(DEBUG) && defined(XP_UNIX)
  45. static int MimeObject_debug_print (MimeObject *, FILE *, int32 depth);
  46. #endif
  47.  
  48. static int
  49. MimeObjectClassInitialize(MimeObjectClass *class)
  50. {
  51.   XP_ASSERT(!class->class_initialized);
  52.   class->initialize   = MimeObject_initialize;
  53.   class->finalize     = MimeObject_finalize;
  54.   class->parse_begin  = MimeObject_parse_begin;
  55.   class->parse_buffer = MimeObject_parse_buffer;
  56.   class->parse_line   = MimeObject_parse_line;
  57.   class->parse_eof    = MimeObject_parse_eof;
  58.   class->parse_end    = MimeObject_parse_end;
  59.   class->displayable_inline_p = MimeObject_displayable_inline_p;
  60.  
  61. #if defined(DEBUG) && defined(XP_UNIX)
  62.   class->debug_print  = MimeObject_debug_print;
  63. #endif
  64.   return 0;
  65. }
  66.  
  67.  
  68. static int
  69. MimeObject_initialize (MimeObject *obj)
  70. {
  71.   /* This is an abstract class; it shouldn't be directly instanciated. */
  72.   XP_ASSERT(obj->class != &mimeObjectClass);
  73.  
  74.   /* Set up the content-type and encoding. */
  75.   if (!obj->content_type && obj->headers)
  76.     obj->content_type = MimeHeaders_get (obj->headers, HEADER_CONTENT_TYPE,
  77.                                          TRUE, FALSE);
  78.   if (!obj->encoding && obj->headers)
  79.     obj->encoding = MimeHeaders_get (obj->headers,
  80.                                      HEADER_CONTENT_TRANSFER_ENCODING,
  81.                                      TRUE, FALSE);
  82.  
  83.  
  84.   /* Special case to normalize some types and encodings to a canonical form.
  85.      (These are nonstandard types/encodings which have been seen to appear in
  86.      multiple forms; we normalize them so that things like looking up icons
  87.      and extensions has consistent behavior for the receiver, regardless of
  88.      the "alias" type that the sender used.)
  89.    */
  90.   if (!obj->content_type)
  91.     ;
  92.   else if (!strcasecomp(obj->content_type, APPLICATION_UUENCODE2) ||
  93.            !strcasecomp(obj->content_type, APPLICATION_UUENCODE3) ||
  94.            !strcasecomp(obj->content_type, APPLICATION_UUENCODE4))
  95.     {
  96.       XP_FREE(obj->content_type);
  97.       obj->content_type = XP_STRDUP(APPLICATION_UUENCODE);
  98.     }
  99.   else if (!strcasecomp(obj->content_type, IMAGE_XBM2) ||
  100.            !strcasecomp(obj->content_type, IMAGE_XBM3))
  101.     {
  102.       XP_FREE(obj->content_type);
  103.       obj->content_type = XP_STRDUP(IMAGE_XBM);
  104.     }
  105.  
  106.   if (!obj->encoding)
  107.     ;
  108.   else if (!strcasecomp(obj->encoding, ENCODING_UUENCODE2) ||
  109.            !strcasecomp(obj->encoding, ENCODING_UUENCODE3) ||
  110.            !strcasecomp(obj->encoding, ENCODING_UUENCODE4))
  111.     {
  112.       XP_FREE(obj->encoding);
  113.       obj->encoding = XP_STRDUP(ENCODING_UUENCODE);
  114.     }
  115.   else if (!strcasecomp(obj->encoding, ENCODING_COMPRESS2))
  116.     {
  117.       XP_FREE(obj->encoding);
  118.       obj->encoding = XP_STRDUP(ENCODING_COMPRESS);
  119.     }
  120.   else if (!strcasecomp(obj->encoding, ENCODING_GZIP2))
  121.     {
  122.       XP_FREE(obj->encoding);
  123.       obj->encoding = XP_STRDUP(ENCODING_GZIP);
  124.     }
  125.  
  126.  
  127.   return 0;
  128. }
  129.  
  130. static void
  131. MimeObject_finalize (MimeObject *obj)
  132. {
  133.   obj->class->parse_eof (obj, FALSE);
  134.   obj->class->parse_end (obj, FALSE);
  135.  
  136.   if (obj->headers)
  137.     {
  138.       MimeHeaders_free(obj->headers);
  139.       obj->headers = 0;
  140.     }
  141.  
  142.   /* Should have been freed by parse_eof, but just in case... */
  143.   XP_ASSERT(!obj->ibuffer);
  144.   XP_ASSERT(!obj->obuffer);
  145.   FREEIF (obj->ibuffer);
  146.   FREEIF (obj->obuffer);
  147.  
  148.   FREEIF(obj->content_type);
  149.   FREEIF(obj->encoding);
  150.  
  151.   if (obj->options && obj->options->state)
  152.     {
  153.       XP_FREE(obj->options->state);
  154.       obj->options->state = 0;
  155.     }
  156. }
  157.  
  158.  
  159. static int
  160. MimeObject_parse_begin (MimeObject *obj)
  161. {
  162.   XP_ASSERT (!obj->closed_p);
  163.  
  164.   /* If we haven't set up the state object yet, then this should be
  165.      the outermost object... */
  166.   if (obj->options && !obj->options->state)
  167.     {
  168.       XP_ASSERT(!obj->headers);  /* should be the outermost object. */
  169.  
  170.       obj->options->state = XP_NEW(MimeParseStateObject);
  171.       if (!obj->options->state) return MK_OUT_OF_MEMORY;
  172.       XP_MEMSET(obj->options->state, 0, sizeof(*obj->options->state));
  173.       obj->options->state->root = obj;
  174.       obj->options->state->separator_suppressed_p = TRUE; /* no first sep */
  175.     }
  176.  
  177.   /* Decide whether this object should be output or not... */
  178.   if (!obj->options || !obj->options->output_fn)
  179.     obj->output_p = FALSE;
  180.   else if (!obj->options->part_to_load)
  181.     obj->output_p = TRUE;
  182.   else
  183.     {
  184.       char *id = mime_part_address(obj);
  185.       if (!id) return MK_OUT_OF_MEMORY;
  186.       obj->output_p = !XP_STRCMP(id, obj->options->part_to_load);
  187.       XP_FREE(id);
  188.     }
  189.  
  190. #ifndef MOZILLA_30
  191. /* Way to destroy any notions of modularity or class hierarchy, Terry! */
  192.   if (obj->options && obj->options->nice_html_only_p) {
  193.       if (!mime_subclass_p(obj->class,
  194.                            (MimeObjectClass*) &mimeInlineTextHTMLClass) &&
  195.           !mime_subclass_p(obj->class,
  196.                            (MimeObjectClass*) &mimeInlineTextPlainClass) &&
  197.           !mime_subclass_p(obj->class,
  198.                            (MimeObjectClass*) &mimeContainerClass)) {
  199.           obj->output_p = FALSE;
  200.       }
  201.   }
  202. #endif /* !MOZILLA_30 */
  203.  
  204.   return 0;
  205. }
  206.  
  207. static int
  208. MimeObject_parse_buffer (char *buffer, int32 size, MimeObject *obj)
  209. {
  210.   XP_ASSERT(!obj->closed_p);
  211.   if (obj->closed_p) return -1;
  212.  
  213.   return msg_LineBuffer (buffer, size,
  214.                          &obj->ibuffer, &obj->ibuffer_size, &obj->ibuffer_fp,
  215.                          TRUE,
  216.                          ((int (*) (char *, int32, void *))
  217.                           /* This cast is to turn void into MimeObject */
  218.                           obj->class->parse_line),
  219.                          obj);
  220. }
  221.  
  222.  
  223. static int
  224. MimeObject_parse_line (char *line, int32 length, MimeObject *obj)
  225. {
  226.   /* This method should never be called. */
  227.   XP_ASSERT(0);
  228.   return -1;
  229. }
  230.  
  231. static int
  232. MimeObject_parse_eof (MimeObject *obj, XP_Bool abort_p)
  233. {
  234.   if (obj->closed_p) return 0;
  235.   XP_ASSERT(!obj->parsed_p);
  236.  
  237.   /* If there is still data in the ibuffer, that means that the last line of
  238.      this part didn't end in a newline; so push it out anyway (this means that
  239.      the parse_line method will be called with a string with no trailing
  240.      newline, which isn't the usual case.)
  241.    */
  242.   if (!abort_p &&
  243.       obj->ibuffer_fp > 0)
  244.     {
  245.       int status = obj->class->parse_line (obj->ibuffer, obj->ibuffer_fp, obj);
  246.       obj->ibuffer_fp = 0;
  247.       if (status < 0)
  248.         {
  249.           obj->closed_p = TRUE;
  250.           return status;
  251.         }
  252.     }
  253.  
  254.   obj->closed_p = TRUE;
  255.   return 0;
  256. }
  257.  
  258.  
  259. static int
  260. MimeObject_parse_end (MimeObject *obj, XP_Bool abort_p)
  261. {
  262.   if (obj->parsed_p)
  263.     {
  264.       XP_ASSERT(obj->closed_p);
  265.       return 0;
  266.     }
  267.  
  268.   /* We won't be needing these buffers any more; nuke 'em. */
  269.   FREEIF(obj->ibuffer);
  270.   obj->ibuffer_fp = 0;
  271.   obj->ibuffer_size = 0;
  272.   FREEIF(obj->obuffer);
  273.   obj->obuffer_fp = 0;
  274.   obj->obuffer_size = 0;
  275.  
  276.   obj->parsed_p = TRUE;
  277.   return 0;
  278. }
  279.  
  280.  
  281. static XP_Bool
  282. MimeObject_displayable_inline_p (MimeObjectClass *class, MimeHeaders *hdrs)
  283. {
  284.   XP_ASSERT(0);  /* This method should never be called. */
  285.   return FALSE;
  286. }
  287.  
  288.  
  289.  
  290. #if defined(DEBUG) && defined(XP_UNIX)
  291. static int
  292. MimeObject_debug_print (MimeObject *obj, FILE *stream, int32 depth)
  293. {
  294.   int i;
  295.   char *addr = mime_part_address(obj);
  296.   for (i=0; i < depth; i++)
  297.     fprintf(stream, "  ");
  298.   fprintf(stream, "<%s %s 0x%08X>\n", obj->class->class_name,
  299.           addr ? addr : "???",
  300.           (uint32) obj);
  301.   FREEIF(addr);
  302.   return 0;
  303. }
  304. #endif
  305.