Back to index

lightning-sunbird  0.9+nobinonly
mimecont.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 #include "prmem.h"
00038 #include "plstr.h"
00039 #include "prlog.h"
00040 #include "nsCRT.h"
00041 #include "prio.h"
00042 #include "mimecont.h"
00043 #include "nsMimeStringResources.h"
00044 
00045 #define MIME_SUPERCLASS mimeObjectClass
00046 MimeDefClass(MimeContainer, MimeContainerClass,
00047                       mimeContainerClass, &MIME_SUPERCLASS);
00048 
00049 static int MimeContainer_initialize (MimeObject *);
00050 static void MimeContainer_finalize (MimeObject *);
00051 static int MimeContainer_add_child (MimeObject *, MimeObject *);
00052 static int MimeContainer_parse_eof (MimeObject *, PRBool);
00053 static int MimeContainer_parse_end (MimeObject *, PRBool);
00054 static PRBool MimeContainer_displayable_inline_p (MimeObjectClass *clazz,
00055                                                                                        MimeHeaders *hdrs);
00056 
00057 #if defined(DEBUG) && defined(XP_UNIX)
00058 static int MimeContainer_debug_print (MimeObject *, PRFileDesc *, PRInt32 depth);
00059 #endif
00060 
00061 static int
00062 MimeContainerClassInitialize(MimeContainerClass *clazz)
00063 {
00064   MimeObjectClass *oclass = (MimeObjectClass *) &clazz->object;
00065 
00066   NS_ASSERTION(!oclass->class_initialized, "1.1 <rhp@netscape.com> 19 Mar 1999 12:00");
00067   oclass->initialize  = MimeContainer_initialize;
00068   oclass->finalize    = MimeContainer_finalize;
00069   oclass->parse_eof   = MimeContainer_parse_eof;
00070   oclass->parse_end   = MimeContainer_parse_end;
00071   oclass->displayable_inline_p = MimeContainer_displayable_inline_p;
00072   clazz->add_child    = MimeContainer_add_child;
00073 
00074 #if defined(DEBUG) && defined(XP_UNIX)
00075   oclass->debug_print = MimeContainer_debug_print;
00076 #endif
00077   return 0;
00078 }
00079 
00080 
00081 static int
00082 MimeContainer_initialize (MimeObject *object)
00083 {
00084   /* This is an abstract class; it shouldn't be directly instantiated. */
00085   NS_ASSERTION(object->clazz != (MimeObjectClass *) &mimeContainerClass, "1.1 <rhp@netscape.com> 19 Mar 1999 12:00");
00086 
00087   return ((MimeObjectClass*)&MIME_SUPERCLASS)->initialize(object);
00088 }
00089 
00090 static void
00091 MimeContainer_finalize (MimeObject *object)
00092 {
00093   MimeContainer *cont = (MimeContainer *) object;
00094 
00095   /* Do this first so that children have their parse_eof methods called
00096         in forward order (0-N) but are destroyed in backward order (N-0)
00097    */
00098   if (!object->closed_p)
00099        object->clazz->parse_eof (object, PR_FALSE);
00100   if (!object->parsed_p)
00101        object->clazz->parse_end (object, PR_FALSE);
00102 
00103   if (cont->children)
00104        {
00105          int i;
00106          for (i = cont->nchildren-1; i >= 0; i--)
00107               {
00108                 MimeObject *kid = cont->children[i];
00109                 if (kid)
00110                      mime_free(kid);
00111                 cont->children[i] = 0;
00112               }
00113          PR_FREEIF(cont->children);
00114          cont->nchildren = 0;
00115        }
00116   ((MimeObjectClass*)&MIME_SUPERCLASS)->finalize(object);
00117 }
00118 
00119 static int
00120 MimeContainer_parse_eof (MimeObject *object, PRBool abort_p)
00121 {
00122   MimeContainer *cont = (MimeContainer *) object;
00123   int status;
00124 
00125   /* We must run all of this object's parent methods first, to get all the
00126         data flushed down its stream, so that the children's parse_eof methods
00127         can access it.  We do not access *this* object again after doing this,
00128         only its children.
00129    */
00130   status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_eof(object, abort_p);
00131   if (status < 0) return status;
00132 
00133   if (cont->children)
00134        {
00135          int i;
00136          for (i = 0; i < cont->nchildren; i++)
00137               {
00138                 MimeObject *kid = cont->children[i];
00139                 if (kid && !kid->closed_p)
00140                      {
00141                        int lstatus = kid->clazz->parse_eof(kid, abort_p);
00142                        if (lstatus < 0) return lstatus;
00143                      }
00144               }
00145        }
00146   return 0;
00147 }
00148 
00149 static int
00150 MimeContainer_parse_end (MimeObject *object, PRBool abort_p)
00151 {
00152   MimeContainer *cont = (MimeContainer *) object;
00153   int status;
00154 
00155   /* We must run all of this object's parent methods first, to get all the
00156         data flushed down its stream, so that the children's parse_eof methods
00157         can access it.  We do not access *this* object again after doing this,
00158         only its children.
00159    */
00160   status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_end(object, abort_p);
00161   if (status < 0) return status;
00162 
00163   if (cont->children)
00164        {
00165          int i;
00166          for (i = 0; i < cont->nchildren; i++)
00167               {
00168                 MimeObject *kid = cont->children[i];
00169                 if (kid && !kid->parsed_p)
00170                      {
00171                        int lstatus = kid->clazz->parse_end(kid, abort_p);
00172                        if (lstatus < 0) return lstatus;
00173                      }
00174               }
00175        }
00176   return 0;
00177 }
00178 
00179 static int
00180 MimeContainer_add_child (MimeObject *parent, MimeObject *child)
00181 {
00182   MimeContainer *cont = (MimeContainer *) parent;
00183   MimeObject **old_kids, **new_kids;
00184 
00185   NS_ASSERTION(parent && child, "1.1 <rhp@netscape.com> 19 Mar 1999 12:00");
00186   if (!parent || !child) return -1;
00187 
00188   old_kids = cont->children;
00189   new_kids = (MimeObject **)PR_MALLOC(sizeof(MimeObject *) * (cont->nchildren + 1));
00190   if (!new_kids) return MIME_OUT_OF_MEMORY;
00191   
00192   if (cont->nchildren > 0)
00193     memcpy(new_kids, old_kids, sizeof(MimeObject *) * cont->nchildren);
00194   new_kids[cont->nchildren] = child;
00195   PR_Free(old_kids);
00196   cont->children = new_kids;
00197   cont->nchildren++;
00198 
00199   child->parent = parent;
00200 
00201   /* Copy this object's options into the child. */
00202   child->options = parent->options;
00203 
00204   return 0;
00205 }
00206 
00207 static PRBool
00208 MimeContainer_displayable_inline_p (MimeObjectClass *clazz, MimeHeaders *hdrs)
00209 {
00210   return PR_TRUE;
00211 }
00212 
00213 
00214 #if defined(DEBUG) && defined(XP_UNIX)
00215 static int
00216 MimeContainer_debug_print (MimeObject *obj, PRFileDesc *stream, PRInt32 depth)
00217 {
00218   MimeContainer *cont = (MimeContainer *) obj;
00219   int i;
00220   char *addr = mime_part_address(obj);
00221   for (i=0; i < depth; i++)
00222   PR_Write(stream, "  ", 2);
00223   /*
00224   PR_Write(stream, "<%s %s (%d kid%s) 0x%08X>\n",
00225                 obj->clazz->class_name,
00226                 addr ? addr : "???",
00227                 cont->nchildren, (cont->nchildren == 1 ? "" : "s"),
00228                 (PRUint32) cont);
00229   */
00230   PR_FREEIF(addr);
00231 
00232 /*
00233   if (cont->nchildren > 0)
00234        fprintf(stream, "\n");
00235  */
00236 
00237   for (i = 0; i < cont->nchildren; i++)
00238        {
00239          MimeObject *kid = cont->children[i];
00240          int status = kid->clazz->debug_print (kid, stream, depth+1);
00241          if (status < 0) return status;
00242        }
00243 
00244 /*
00245   if (cont->nchildren > 0)
00246        fprintf(stream, "\n");
00247  */
00248 
00249   return 0;
00250 }
00251 #endif