PR_ASSERT(relobj->file_buffer_name); if (!relobj->file_buffer_name) {
PR_ASSERT(relobj->file_buffer_spec); if (!relobj->file_buffer_spec) {
MimeMultipartRelated_parse_eof (MimeObject *obj, PRBool abort_p){	/* OK, all the necessary data has been collected.  We now have to spew out	   the HTML.  We let it go through all the normal mechanisms (which	   includes content-encoding handling), and intercept the output data to do	   translation of the tags.  Whee. */	MimeMultipartRelated *relobj = (MimeMultipartRelated *) obj;	int status = 0;	MimeObject *body;	char* ct;	const char* dct;	status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_eof(obj, abort_p);	if (status < 0) goto FAIL;	if (!relobj->headobj) return 0;	ct = (relobj->buffered_hdrs		  ? MimeHeaders_get (relobj->buffered_hdrs, HEADER_CONTENT_TYPE,							 PR_TRUE, PR_FALSE)		  : 0);	dct = (((MimeMultipartClass *) obj->clazz)->default_part_type);	relobj->real_output_fn = obj->options->output_fn;	relobj->real_output_closure = obj->options->output_closure;	obj->options->output_fn = mime_multipart_related_output_fn;	obj->options->output_closure = obj;	body = mime_create(((ct && *ct) ? ct : (dct ? dct : TEXT_HTML)),					   relobj->buffered_hdrs, obj->options);	if (!body) {		status = MIME_OUT_OF_MEMORY;		goto FAIL;	}	status = ((MimeContainerClass *) obj->clazz)->add_child(obj, body);	if (status < 0) {		mime_free(body);		goto FAIL;	}#ifdef MIME_DRAFTS	if ( obj->options && 	   obj->options->decompose_file_p &&	   obj->options->decompose_file_init_fn &&	   (relobj->file_buffer_name || relobj->head_buffer))	{	  status = obj->options->decompose_file_init_fn ( obj->options->stream_closure,													  relobj->buffered_hdrs );	  if (status < 0) return status;	}#endif /* MIME_DRAFTS */	/* Now that we've added this new object to our list of children,	   start its parser going. */	status = body->clazz->parse_begin(body);	if (status < 0) goto FAIL;		if (relobj->head_buffer) {		/* Read it out of memory. */		PR_ASSERT(!relobj->file_buffer_name && !relobj->file_stream);		status = body->clazz->parse_buffer(relobj->head_buffer,											   relobj->head_buffer_fp,											   body);	} else if (relobj->file_buffer_name) {		/* Read it off disk.		 */		char *buf;		PRInt32 buf_size = 10 * 1024;  /* 10k; tune this? */		PR_ASSERT(relobj->head_buffer_size == 0 &&				  relobj->head_buffer_fp == 0);		PR_ASSERT(relobj->file_buffer_name);		if (!relobj->file_buffer_name) {			status = -1;			goto FAIL;		}		buf = (char *) PR_MALLOC(buf_size);		if (!buf) {			status = MIME_OUT_OF_MEMORY;			goto FAIL;		}		if (relobj->file_stream) {			PR_Close(relobj->file_stream);		}		relobj->file_stream = PR_Open(relobj->file_buffer_name,						  PR_RDONLY, 0);		if (!relobj->file_stream) {			PR_Free(buf);			status = MIME_UNABLE_TO_OPEN_TMP_FILE;			goto FAIL;		}		while(1) {			PRInt32 rstatus = PR_Read(relobj->file_stream,						buf, buf_size - 1);			if (rstatus <= 0) {				status = rstatus;				break;			} else {				/* It would be really nice to be able to yield here, and let				   some user events and other input sources get processed.				   Oh well. */				status = body->clazz->parse_buffer(buf, rstatus, body);				if (status < 0) break;			}		}		PR_Free(buf);	}  if (status < 0) goto FAIL;  /* Done parsing. */  status = body->clazz->parse_eof(body, PR_FALSE);  if (status < 0) goto FAIL;  status = body->clazz->parse_end(body, PR_FALSE);  if (status < 0) goto FAIL;FAIL:#ifdef MIME_DRAFTS  if ( obj->options &&	   obj->options->decompose_file_p &&	   obj->options->decompose_file_close_fn &&	   (relobj->file_buffer_name || relobj->head_buffer)) {	status = obj->options->decompose_file_close_fn ( obj->options->stream_closure );	if (status < 0) return status;  }#endif /* MIME_DRAFTS */  relobj->headobj = NULL;  obj->options->output_fn = relobj->real_output_fn;  obj->options->output_closure = relobj->real_output_closure;  return status;}	