dashdashspace = -1; } PRBool firstSpaceNbsp = PR_FALSE;    PRBool nextSpaceIsNbsp = firstSpaceNbsp; while(*templinep && (*templinep != '\r') && (*templinep != '\n')) {   if(dashdashspace>=0) { switch(dashdashspace) { case 0: case 1: if('-' == *templinep) dashdashspace++; else dashdashspace=-1; break; case 2: if(' ' == *templinep) dashdashspace++; else dashdashspace=-1; break; default: dashdashspace = -1;
while(*templinep && (*templinep != '\r') && (*templinep != '\n')) { uint32 intag = 0; const PRBool firstSpaceNbsp = PR_FALSE;    PRBool nextSpaceIsNbsp = firstSpaceNbsp;  if ('<' == *templinep) intag = 1; if (!intag) { if ((' ' == *templinep) && !exdata->inflow) { if (nextSpaceIsNbsp) { *outlinep='&'; outlinep++; *outlinep='n'; outlinep++; *outlinep='b'; outlinep++; *outlinep='s'; outlinep++; *outlinep='p'; outlinep++; *outlinep=';'; outlinep++; } else { *outlinep=' '; outlinep++; } nextSpaceIsNbsp = PR_TRUE; templinep++; } else if(('\t' == *templinep) && !exdata->inflow) {  for(int spaces=0; spaces<4; spaces++) { if (nextSpaceIsNbsp) { *outlinep='&'; outlinep++; *outlinep='n'; outlinep++; *outlinep='b'; outlinep++; *outlinep='s'; outlinep++; *outlinep='p'; outlinep++; *outlinep=';'; outlinep++; } else { *outlinep=' '; outlinep++; } nextSpaceIsNbsp = PR_TRUE; } templinep++; } else { nextSpaceIsNbsp = firstSpaceNbsp; *outlinep = *templinep; outlinep++; templinep++; } } else {  nextSpaceIsNbsp = firstSpaceNbsp; *outlinep = *templinep; outlinep++; templinep++;
MimeInlineTextPlainFlowed_parse_line (char *line, PRInt32 length, MimeObject *obj){  int status;  PRBool quoting = ( obj->options    && ( obj->options->format_out == nsMimeOutput::nsMimeMessageQuoting ||         obj->options->format_out == nsMimeOutput::nsMimeMessageBodyQuoting       )           );  // see above  PRBool plainHTML = quoting || (obj->options &&       obj->options->format_out == nsMimeOutput::nsMimeMessageSaveAs);       // see above  struct MimeInlineTextPlainFlowedExData *exdata;  exdata = MimeInlineTextPlainFlowedExDataList;  while(exdata && (exdata->ownerobj != obj)) {    exdata = exdata->next;  }  NS_ASSERTION(exdata, "The extra data has disappeared!");  NS_ASSERTION(length > 0, "zero length");  if (length <= 0) return 0;  // Look if the last character (after stripping ending end  // of lines) is a SPACE. If it is, we are looking at a  // flowed line. Normally we assume that the last two chars  // are CR and LF as said in RFC822, but that doesn't seem to  // be the case always.  PRBool flowed = PR_FALSE;  PRInt32 index = length-1;  while(index >= 0 &&        (('\r' == line[index]) || ('\n' == line[index]))) {    index--;  }  if((index >= 0) && (' ' == line[index])) {    flowed = PR_TRUE;  }    // Grows the buffer if needed for this line  // calculate needed buffersize. Use the linelength  // and then double it to compensate for text converted  // to links. Then add 15 for each '>' (blockquote) and  // 20 for each ':' and '@'. (overhead in conversion to  // links). Also add 5 for every '\r' or \n' and 7 for each  // space in case they have to be replaced by &nbsp;  int32 buffersizeneeded = length * 2 + 15*exdata->quotelevel;  for(int32 i=0; i<length; i++) {    switch(line[i]) {    case '>': buffersizeneeded += 25; break; // '>' -> '<blockquote type=cite>'    case '<': buffersizeneeded += 5; break; // '<' -> '&lt;'    case ':': buffersizeneeded += 20; break;    case '@': buffersizeneeded += 20; break;    case '\r': buffersizeneeded += 5; break;    case '\n': buffersizeneeded += 5; break;    case ' ': buffersizeneeded += 7; break; // Not very good for other charsets    case '\t': buffersizeneeded += 30; break;    default: break; // Nothing    }  }  buffersizeneeded += 30; // For possible <nobr> ... </nobr>  /* There is the issue of guessing how much space we will need for emoticons.     So what we will do is count the total number of "special" chars and     multiply by 82 (max len for a smiley line) and add one for good measure.*/  PRInt32   specialCharCount = 0;  for (PRInt32 z=0; z<length; z++)  {     if ( (line[z] == ')') || (line[z] == '(') || (line[z] == ':')         || (line[z] == ';') || (line[z] == '>') )      ++specialCharCount;  }  buffersizeneeded += 82 * (specialCharCount + 1);   status = MimeObject_grow_obuffer (obj, buffersizeneeded);  if (status < 0) return status;  char *templine = (char *)PR_CALLOC(buffersizeneeded);  if(!templine)     return MIME_OUT_OF_MEMORY;  // Copy `line' to `templine', quoting HTML along the way.	// Note: this function does no charset conversion; that has already	// been done.  //  uint32 linequotelevel = 0;  char *linep = line;  // Space stuffed?  if(' ' == *linep) {    linep++;  } else {    // count '>':s before the first non-'>'    while('>' == *linep) {      linep++;      linequotelevel++;    }    // Space stuffed?    if(' ' == *linep) {      linep++;    }  }  mozITXTToHTMLConv *conv = GetTextConverter(obj->options);  PRBool skipConversion = !conv ||                          (obj->options && obj->options->force_user_charset);      if (!skipConversion)  {    nsString strline;    strline.AssignWithConversion(linep, (length - (linep - line)) );    PRUnichar* wresult = nsnull;    nsresult rv = NS_OK;    PRBool whattodo = obj->options->whattodo;    if (plainHTML)    {      if (quoting)        whattodo = 0;      else        whattodo = whattodo & ~mozITXTToHTMLConv::kGlyphSubstitution;                   /* Do recognition for the case, the result is viewed in                      Mozilla, but not GlyphSubstitution, because other UAs                      might not be able to display the glyphs. */    }    rv = conv->ScanTXT(strline.GetUnicode(), whattodo, &wresult);    if (NS_FAILED(rv))      return -1;    /* avoid an extra string copy by using nsSubsumeStr, this transfers       ownership of wresult to strresult so don't try to free wresult later. */    nsSubsumeStr strresult(wresult, PR_TRUE /* assume ownership */);    /* avoid yet another extra string copy of the line by using .ToCString       which will convert and copy directly into the buffer we have already       allocated. */    strresult.ToCString(templine, buffersizeneeded - 10);   }  else  {    nsCRT::memcpy(templine, line, length);    templine[length] = '\0';    status = NS_OK;  }  if (status != NS_OK) {    PR_Free(templine);    return status;  }  //  NS_ASSERTION(*line == 0 || *obj->obuffer, "have line or buffer");  NS_ASSERTION(*line == 0 || *templine, "have line or buffer");  char *templinep = templine;  char *outlinep = obj->obuffer;  /* Correct number of blockquotes */  int32 quoteleveldiff=linequotelevel - exdata->quotelevel;  if((quoteleveldiff != 0) && flowed && exdata->inflow) {    // From RFC 2646 4.5    // The receiver SHOULD handle this error by using the 'quote-depth-wins' rule,    // which is to ignore the flowed indicator and treat the line as fixed.  That    // is, the change in quote depth ends the paragraph.    // We get that behaviour by just going on.  }  while(quoteleveldiff>0) {    quoteleveldiff--;    /* Output <blockquote> */    *outlinep='<'; outlinep++;    *outlinep='/'; outlinep++;    *outlinep='t'; outlinep++;    *outlinep='t'; outlinep++;    *outlinep='>'; outlinep++;    *outlinep='<'; outlinep++;    *outlinep='b'; outlinep++;    *outlinep='l'; outlinep++;    *outlinep='o'; outlinep++;    *outlinep='c'; outlinep++;    *outlinep='k'; outlinep++;    *outlinep='q'; outlinep++;    *outlinep='u'; outlinep++;    *outlinep='o'; outlinep++;    *outlinep='t'; outlinep++;    *outlinep='e'; outlinep++;    *outlinep=' '; outlinep++;    *outlinep='t'; outlinep++;    *outlinep='y'; outlinep++;    *outlinep='p'; outlinep++;    *outlinep='e'; outlinep++;    *outlinep='='; outlinep++;    *outlinep='c'; outlinep++;    *outlinep='i'; outlinep++;    *outlinep='t'; outlinep++;    *outlinep='e'; outlinep++;    // This is to have us observe the user pref settings for citations    MimeInlineTextPlainFlowed *tObj = (MimeInlineTextPlainFlowed *) obj;    char *style = MimeTextBuildPrefixCSS(tObj->mQuotedSizeSetting,                                         tObj->mQuotedStyleSetting,                                         tObj->mCitationColor);    if (!plainHTML && style && strlen(style))    {      *outlinep=' '; outlinep++;      *outlinep='s'; outlinep++;      *outlinep='t'; outlinep++;      *outlinep='y'; outlinep++;      *outlinep='l'; outlinep++;      *outlinep='e'; outlinep++;      *outlinep='='; outlinep++;      *outlinep='\"'; outlinep++;      strcpy(outlinep, style);      outlinep += nsCRT::strlen(style);      *outlinep='\"'; outlinep++;      PR_FREEIF(style);    }    *outlinep='>'; outlinep++;    *outlinep='<'; outlinep++;    *outlinep='t'; outlinep++;    *outlinep='t'; outlinep++;    *outlinep='>'; outlinep++;  }  while(quoteleveldiff<0) {    quoteleveldiff++;    /* Output </blockquote> */    *outlinep='<'; outlinep++;    *outlinep='/'; outlinep++;    *outlinep='t'; outlinep++;    *outlinep='t'; outlinep++;    *outlinep='>'; outlinep++;    *outlinep='<'; outlinep++;    *outlinep='/'; outlinep++;    *outlinep='b'; outlinep++;    *outlinep='l'; outlinep++;    *outlinep='o'; outlinep++;    *outlinep='c'; outlinep++;    *outlinep='k'; outlinep++;    *outlinep='q'; outlinep++;    *outlinep='u'; outlinep++;    *outlinep='o'; outlinep++;    *outlinep='t'; outlinep++;    *outlinep='e'; outlinep++;    *outlinep='>'; outlinep++;    *outlinep='<'; outlinep++;    *outlinep='t'; outlinep++;    *outlinep='t'; outlinep++;    *outlinep='>'; outlinep++;  }  exdata->quotelevel = linequotelevel;  if(flowed) {    int32 dashdashspace; // Check for RFC 2646 4.3    if((0==linequotelevel) && !exdata->inflow){      // possible      dashdashspace = 0;    } else {      dashdashspace = -1;    }    PRBool firstSpaceNbsp = PR_FALSE;   /* Convert all spaces but         the first in a row into nbsp (i.e. always wrap) */    PRBool nextSpaceIsNbsp = firstSpaceNbsp;    while(*templinep && (*templinep != '\r') && (*templinep != '\n')) {      // Check RFC 2646 "4.3. Usenet Signature Convention": "-- "+CRLF is      // not a flowed line      if(dashdashspace>=0) {        switch(dashdashspace) {        case 0: // First and second '-'        case 1:          if('-' == *templinep)            dashdashspace++;          else            dashdashspace=-1;          break;        case 2:          if(' ' == *templinep)            dashdashspace++;          else            dashdashspace=-1;          break;        default:          dashdashspace = -1;        }      } // end if(dashdashspace...)      // Output the same character      // Here, the most of the flowing text is written      // DELETEME: What is this intag in the fixed code and do we need it here?      if((' ' == *templinep) && !exdata->inflow) {        if (nextSpaceIsNbsp)        {          *outlinep='&'; outlinep++;          *outlinep='n'; outlinep++;          *outlinep='b'; outlinep++;          *outlinep='s'; outlinep++;          *outlinep='p'; outlinep++;          *outlinep=';'; outlinep++;        }        else        {          *outlinep=' '; outlinep++;        }        nextSpaceIsNbsp = PR_TRUE;        templinep++;      } else if(('\t' == *templinep) && !exdata->inflow) {        // Output 4 "spaces"        for(int spaces=0; spaces<4; spaces++) {          if (nextSpaceIsNbsp)          {            *outlinep='&'; outlinep++;            *outlinep='n'; outlinep++;            *outlinep='b'; outlinep++;            *outlinep='s'; outlinep++;            *outlinep='p'; outlinep++;            *outlinep=';'; outlinep++;          }          else          {            *outlinep=' '; outlinep++;          }          nextSpaceIsNbsp = PR_TRUE;        }        templinep++;      } else {        nextSpaceIsNbsp = firstSpaceNbsp;        *outlinep = *templinep;        outlinep++;        templinep++;      }           }    if(3 == dashdashspace) {      // "-- " is a fixed line.       *outlinep='<'; outlinep++;      *outlinep='b'; outlinep++;      *outlinep='r'; outlinep++;      *outlinep='>'; outlinep++;    }    exdata->inflow=PR_TRUE;  } else {    // Fixed    /*    // Output the stripped '>':s    while(linequotelevel) {      // output '>'      *outlinep='&'; outlinep++;      *outlinep='g'; outlinep++;      *outlinep='t'; outlinep++;      *outlinep=';'; outlinep++;      linequotelevel--;    }    */        uint32 intag = 0;     PRBool firstSpaceNbsp = !plainHTML && !obj->options->wrap_long_lines_p;         /* If wrap, convert all spaces but the first in a row into nbsp,            otherwise all. */    PRBool nextSpaceIsNbsp = firstSpaceNbsp;    while(*templinep && (*templinep != '\r') && (*templinep != '\n')) {      if('<' == *templinep) intag = 1;      if(!intag) {        if((' ' == *templinep) && !exdata->inflow) {          if (nextSpaceIsNbsp)          {            *outlinep='&'; outlinep++;            *outlinep='n'; outlinep++;            *outlinep='b'; outlinep++;            *outlinep='s'; outlinep++;            *outlinep='p'; outlinep++;            *outlinep=';'; outlinep++;          }          else          {            *outlinep=' '; outlinep++;          }          nextSpaceIsNbsp = PR_TRUE;          templinep++;        } else if(('\t' == *templinep) && !exdata->inflow) {          // Output 4 "spaces"          for(int spaces=0; spaces<4; spaces++) {            if (nextSpaceIsNbsp)            {              *outlinep='&'; outlinep++;              *outlinep='n'; outlinep++;              *outlinep='b'; outlinep++;              *outlinep='s'; outlinep++;              *outlinep='p'; outlinep++;              *outlinep=';'; outlinep++;            }            else            {              *outlinep=' '; outlinep++;            }            nextSpaceIsNbsp = PR_TRUE;          }          templinep++;        } else {          nextSpaceIsNbsp = firstSpaceNbsp;          *outlinep = *templinep;          outlinep++;          templinep++;        }       } else {        // In tag. Don't change anything        nextSpaceIsNbsp = firstSpaceNbsp;        *outlinep = *templinep;        outlinep++;        templinep++;      }    }        *outlinep='<'; outlinep++;    *outlinep='b'; outlinep++;    *outlinep='r'; outlinep++;    *outlinep='>'; outlinep++;    exdata->inflow = PR_FALSE;  } // End Fixed line  *outlinep='\0'; outlinep++;  PR_Free(templine);  // Calculate linelength as  // <pointer to the next free char>-<pointer to the beginning>-1  // '-1' for the terminating '\0'  return MimeObject_write(obj, obj->obuffer, outlinep-obj->obuffer-1, PR_TRUE);}