*dest++= PRUnichar(ucs4);
*dest++= IS_SURROGATE(ucs4) ? UCS2_REPLACEMENT_CHAR : PRUnichar(ucs4);
static nsresult ConvertCommon(const char * aSrc,                               PRInt32 * aSrcLength,                               PRUnichar * aDest,                               PRInt32 * aDestLength,                              PRUint16 * aState,                              PRUint8  * aBuffer,                              PRBool aIsLE){     NS_ENSURE_TRUE(*aState < 4, NS_ERROR_INVALID_ARG);  NS_ENSURE_TRUE(*aDestLength > 0, NS_ERROR_INVALID_ARG);  const char *src = aSrc;  const char *srcEnd = aSrc + *aSrcLength;     PRUnichar *dest = aDest;  PRUnichar *destEnd = aDest + *aDestLength;  if (*aState > *aSrcLength)   {    memcpy(aBuffer + 4 - *aState, src, *aSrcLength);    *aDestLength = 0;    *aState -= *aSrcLength;    return NS_OK_UDEC_MOREINPUT;  }  PRUint32 ucs4;  // prev. run left a partial UTF-32 seq.   if (*aState > 0)  {    memcpy(aBuffer + 4 - *aState, src, *aState);    ucs4 =  aIsLE ? LE_STRING_TO_UCS4(aBuffer) : BE_STRING_TO_UCS4(aBuffer);     if (ucs4 < 0x10000L)  // BMP    {      // XXX Do we have to convert surrogate code points to the replacement      // character (0xfffd)?        *dest++= PRUnichar(ucs4);    }    else if (ucs4 < 0x110000L)  // plane 1 through plane 16     {      if (destEnd - dest < 2)       {        *aSrcLength = 0;        *aDestLength = 0;        return NS_OK_UDEC_MOREOUTPUT;      }      // ((ucs4 - 0x10000) >> 10) + 0xd800;      *dest++= PRUnichar((ucs4 >> 10) + 0xd7c0);  // high surrogate      *dest++= PRUnichar(ucs4 & 0x3ffL | 0xdc00); // low surrogate    }           // Codepoints in plane 17 and higher (> 0x10ffff)    // are not representable in UTF-16 we use for the internal    // character representation. This is not a problem    // because Unicode/ISO 10646 will never assign characters    // in plane 17 and higher. Therefore, we convert them    // to Unicode replacement character (0xfffd).    else                         *dest++ = 0xfffd;    src += *aState;    *aState = 0;  }  nsresult rv = NS_OK;  // conversion result  for ( ; src < srcEnd && dest < destEnd; src += 4)  {    if (srcEnd - src < 4)     {      // fill up aBuffer until src buffer gets exhausted.      memcpy(aBuffer, src, srcEnd - src);      *aState = 4 - (srcEnd - src); // set add. char to read in next run      src = srcEnd;      rv = NS_OK_UDEC_MOREINPUT;      break;    }    ucs4 =  aIsLE ? LE_STRING_TO_UCS4(src) : BE_STRING_TO_UCS4(src);     if (ucs4 < 0x10000L)  // BMP    {      // XXX Do we have to convert surrogate code points to the replacement      // character (0xfffd)?        *dest++= PRUnichar(ucs4);    }    else if (ucs4 < 0x110000L)  // plane 1 through plane 16     {      if (destEnd - dest < 2)         break;      // ((ucs4 - 0x10000) >> 10) + 0xd800;      *dest++= PRUnichar((ucs4 >> 10) + 0xd7c0);       *dest++= PRUnichar(ucs4 & 0x3ffL | 0xdc00);    }           else                       // plane 17 and higher      *dest++ = 0xfffd;  }  //output not finished, output buffer too short  if((NS_OK == rv) && (src < srcEnd) && (dest >= destEnd))     rv = NS_OK_UDEC_MOREOUTPUT;  *aSrcLength = src - aSrc;  *aDestLength  = dest - aDest;  return rv;}