home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / libmime / mimecont.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  6.2 KB  |  227 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.  
  20. #include "mimecont.h"
  21.  
  22. #define MIME_SUPERCLASS mimeObjectClass
  23. MimeDefClass(MimeContainer, MimeContainerClass,
  24.              mimeContainerClass, &MIME_SUPERCLASS);
  25.  
  26. static int MimeContainer_initialize (MimeObject *);
  27. static void MimeContainer_finalize (MimeObject *);
  28. static int MimeContainer_add_child (MimeObject *, MimeObject *);
  29. static int MimeContainer_parse_eof (MimeObject *, XP_Bool);
  30. static int MimeContainer_parse_end (MimeObject *, XP_Bool);
  31. static XP_Bool MimeContainer_displayable_inline_p (MimeObjectClass *class,
  32.                                                    MimeHeaders *hdrs);
  33.  
  34. #if defined(DEBUG) && defined(XP_UNIX)
  35. static int MimeContainer_debug_print (MimeObject *, FILE *, int32 depth);
  36. #endif
  37.  
  38. static int
  39. MimeContainerClassInitialize(MimeContainerClass *class)
  40. {
  41.   MimeObjectClass *oclass = (MimeObjectClass *) &class->object;
  42.  
  43.   XP_ASSERT(!oclass->class_initialized);
  44.   oclass->initialize  = MimeContainer_initialize;
  45.   oclass->finalize    = MimeContainer_finalize;
  46.   oclass->parse_eof   = MimeContainer_parse_eof;
  47.   oclass->parse_end   = MimeContainer_parse_end;
  48.   oclass->displayable_inline_p = MimeContainer_displayable_inline_p;
  49.   class->add_child    = MimeContainer_add_child;
  50.  
  51. #if defined(DEBUG) && defined(XP_UNIX)
  52.   oclass->debug_print = MimeContainer_debug_print;
  53. #endif
  54.   return 0;
  55. }
  56.  
  57.  
  58. static int
  59. MimeContainer_initialize (MimeObject *object)
  60. {
  61.   /* This is an abstract class; it shouldn't be directly instanciated. */
  62.   XP_ASSERT(object->class != (MimeObjectClass *) &mimeContainerClass);
  63.  
  64.   return ((MimeObjectClass*)&MIME_SUPERCLASS)->initialize(object);
  65. }
  66.  
  67. static void
  68. MimeContainer_finalize (MimeObject *object)
  69. {
  70.   MimeContainer *cont = (MimeContainer *) object;
  71.  
  72.   /* Do this first so that children have their parse_eof methods called
  73.      in forward order (0-N) but are destroyed in backward order (N-0)
  74.    */
  75.   if (!object->closed_p)
  76.     object->class->parse_eof (object, FALSE);
  77.   if (!object->parsed_p)
  78.     object->class->parse_end (object, FALSE);
  79.  
  80.   if (cont->children)
  81.     {
  82.       int i;
  83.       for (i = cont->nchildren-1; i >= 0; i--)
  84.         {
  85.           MimeObject *kid = cont->children[i];
  86.           if (kid)
  87.             mime_free(kid);
  88.           cont->children[i] = 0;
  89.         }
  90.       FREEIF(cont->children);
  91.       cont->nchildren = 0;
  92.     }
  93.   ((MimeObjectClass*)&MIME_SUPERCLASS)->finalize(object);
  94. }
  95.  
  96. static int
  97. MimeContainer_parse_eof (MimeObject *object, XP_Bool abort_p)
  98. {
  99.   MimeContainer *cont = (MimeContainer *) object;
  100.   int status;
  101.  
  102.   /* We must run all of this object's parent methods first, to get all the
  103.      data flushed down its stream, so that the children's parse_eof methods
  104.      can access it.  We do not access *this* object again after doing this,
  105.      only its children.
  106.    */
  107.   status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_eof(object, abort_p);
  108.   if (status < 0) return status;
  109.  
  110.   if (cont->children)
  111.     {
  112.       int i;
  113.       for (i = 0; i < cont->nchildren; i++)
  114.         {
  115.           MimeObject *kid = cont->children[i];
  116.           if (kid && !kid->closed_p)
  117.             {
  118.               int status = kid->class->parse_eof(kid, abort_p);
  119.               if (status < 0) return status;
  120.             }
  121.         }
  122.     }
  123.   return 0;
  124. }
  125.  
  126. static int
  127. MimeContainer_parse_end (MimeObject *object, XP_Bool abort_p)
  128. {
  129.   MimeContainer *cont = (MimeContainer *) object;
  130.   int status;
  131.  
  132.   /* We must run all of this object's parent methods first, to get all the
  133.      data flushed down its stream, so that the children's parse_eof methods
  134.      can access it.  We do not access *this* object again after doing this,
  135.      only its children.
  136.    */
  137.   status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_end(object, abort_p);
  138.   if (status < 0) return status;
  139.  
  140.   if (cont->children)
  141.     {
  142.       int i;
  143.       for (i = 0; i < cont->nchildren; i++)
  144.         {
  145.           MimeObject *kid = cont->children[i];
  146.           if (kid && !kid->parsed_p)
  147.             {
  148.               int status = kid->class->parse_end(kid, abort_p);
  149.               if (status < 0) return status;
  150.             }
  151.         }
  152.     }
  153.   return 0;
  154. }
  155.  
  156. static int
  157. MimeContainer_add_child (MimeObject *parent, MimeObject *child)
  158. {
  159.   MimeContainer *cont = (MimeContainer *) parent;
  160.   MimeObject **old_kids, **new_kids;
  161.  
  162.   XP_ASSERT(parent && child);
  163.   if (!parent || !child) return -1;
  164.  
  165.   old_kids = cont->children;
  166.   new_kids = XP_ALLOC(sizeof(MimeObject *) * (cont->nchildren + 1));
  167.   if (!new_kids) return MK_OUT_OF_MEMORY;
  168.   
  169.   if (cont->nchildren > 0)
  170.     XP_MEMCPY(new_kids, old_kids, sizeof(MimeObject *) * cont->nchildren);
  171.   new_kids[cont->nchildren] = child;
  172.   XP_FREE(old_kids);
  173.   cont->children = new_kids;
  174.   cont->nchildren++;
  175.  
  176.   child->parent = parent;
  177.  
  178.   /* Copy this object's options into the child. */
  179.   child->options = parent->options;
  180.  
  181.   return 0;
  182. }
  183.  
  184. static XP_Bool
  185. MimeContainer_displayable_inline_p (MimeObjectClass *class, MimeHeaders *hdrs)
  186. {
  187.   return TRUE;
  188. }
  189.  
  190.  
  191. #if defined(DEBUG) && defined(XP_UNIX)
  192. static int
  193. MimeContainer_debug_print (MimeObject *obj, FILE *stream, int32 depth)
  194. {
  195.   MimeContainer *cont = (MimeContainer *) obj;
  196.   int i;
  197.   char *addr = mime_part_address(obj);
  198.   for (i=0; i < depth; i++)
  199.     fprintf(stream, "  ");
  200.   fprintf(stream, "<%s %s (%d kid%s) 0x%08X>\n",
  201.           obj->class->class_name,
  202.           addr ? addr : "???",
  203.           cont->nchildren, (cont->nchildren == 1 ? "" : "s"),
  204.           (uint32) cont);
  205.   FREEIF(addr);
  206.  
  207. /*
  208.   if (cont->nchildren > 0)
  209.     fprintf(stream, "\n");
  210.  */
  211.  
  212.   for (i = 0; i < cont->nchildren; i++)
  213.     {
  214.       MimeObject *kid = cont->children[i];
  215.       int status = kid->class->debug_print (kid, stream, depth+1);
  216.       if (status < 0) return status;
  217.     }
  218.  
  219. /*
  220.   if (cont->nchildren > 0)
  221.     fprintf(stream, "\n");
  222.  */
  223.  
  224.   return 0;
  225. }
  226. #endif
  227.