if (length > 0 && line[length-1] == LF) length--; if (length > 0 && line[length-1] == CR) length--;
if (length > 0 && line[length-1] == nsCRT::LF) length--; if (length > 0 && line[length-1] == nsCRT::CR) length--;
MimeMultipartSigned_parse_child_line (MimeObject *obj,									  char *line, PRInt32 length,									  PRBool first_line_p){  MimeMultipartSigned *sig = (MimeMultipartSigned *) obj;  MimeContainer *cont = (MimeContainer *) obj;  int status = 0;  /* Shouldn't have made any sub-parts yet. */  PR_ASSERT(cont->nchildren == 0);  if (cont->nchildren != 0) return -1;  switch (sig->state)	{	case MimeMultipartSignedPreamble:	case MimeMultipartSignedBodyFirstHeader:	case MimeMultipartSignedBodyHeaders:	  PR_ASSERT(0);  /* How'd we get here?  Oh well, fall through. */	case MimeMultipartSignedBodyFirstLine:	  PR_ASSERT(first_line_p);	  if (!sig->part_buffer)		{		  sig->part_buffer = MimePartBufferCreate();		  if (!sig->part_buffer)			return MIME_OUT_OF_MEMORY;		}	  /* fall through */	case MimeMultipartSignedBodyLine:	  {		/* This is the first part; we are buffering it, and will emit it all		   at the end (so that we know whether the signature matches before		   showing anything to the user.)		 */		/* The newline issues here are tricky, since both the newlines		   before and after the boundary string are to be considered part		   of the boundary: this is so that a part can be specified such		   that it does not end in a trailing newline.		   To implement this, we send a newline *before* each line instead		   of after, except for the first line, which is not preceeded by a		   newline.		 */		/* Remove the trailing newline... */		if (length > 0 && line[length-1] == LF) length--;		if (length > 0 && line[length-1] == CR) length--;		PR_ASSERT(sig->part_buffer);		PR_ASSERT(first_line_p ==				  (sig->state == MimeMultipartSignedBodyFirstLine));		if (!first_line_p)		  {			/* Push out a preceeding newline... */			char nl[] = MSG_LINEBREAK;			status = MimePartBufferWrite (sig->part_buffer, nl, MSG_LINEBREAK_LEN);			if (status < 0) return status;		  }		/* Now push out the line sans trailing newline. */		if (length > 0)			status = MimePartBufferWrite (sig->part_buffer, line, length);		if (status < 0) return status;	  }	break;	case MimeMultipartSignedSignatureHeaders:	  PR_ASSERT(0);  /* How'd we get here?  Oh well, fall through. */	case MimeMultipartSignedSignatureFirstLine:	case MimeMultipartSignedSignatureLine:	  /* Nothing to do here -- hashing of the signature part is handled up		 in MimeMultipartSigned_parse_line().	   */	  break;	case MimeMultipartSignedEpilogue:	  /* Too many kids?  MimeMultipartSigned_create_child() should have		 prevented us from getting here. */	  PR_ASSERT(0);	  return -1;	  break;	default: /* bad state */	  PR_ASSERT(0);	  return -1;	  break;	}  return status;}