dstPtr[totalCLength] = '\0'; *outBuffer = dstPtr; *outLength = totalCLength;
PRInt32 MimeCharsetConverterClass::Convert(const char* inBuffer, const PRInt32 inLength,                                            char** outBuffer, PRInt32* outLength,                                           PRInt32* numUnConverted){  nsresult res;  if (NULL != numUnConverted) {    *numUnConverted = 0;  }  // Encoder is not available, duplicate the input.  if (NULL == mEncoder) {    *outBuffer = (char *) PR_Malloc(inLength+1);    if (NULL != *outBuffer) {      nsCRT::memcpy(*outBuffer, inBuffer, inLength);      *outLength = inLength;      (*outBuffer)[inLength] = '\0';      return 0;    }    return -1;  }  nsIUnicodeDecoder* decoder = mDecoder;  nsIUnicodeEncoder* encoder = mEncoder;  // try auto detection for this string  if (mAutoDetect && NULL != mDetector && (mMaxNumCharsDetect == -1 || mMaxNumCharsDetect > mNumChars)) {    nsString aCharsetDetected;    const char* oCharset;    nsDetectionConfident oConfident;    res = mDetector->DoIt(inBuffer, inLength, &oCharset, oConfident);    if (NS_SUCCEEDED(res) && (eBestAnswer == oConfident || eSureAnswer == oConfident)) {      aCharsetDetected.AssignWithConversion(oCharset);      // Check if need a conversion.      if (!NeedCharsetConversion(aCharsetDetected, mOutputCharset)) {        *outBuffer = (char *) PR_Malloc(inLength+1);        if (NULL != *outBuffer) {          nsCRT::memcpy(*outBuffer, inBuffer, inLength);          *outLength = inLength;          (*outBuffer)[inLength] = '\0';          return 0;        }        return -1;      }      else {        NS_WITH_SERVICE(nsICharsetConverterManager, ccm, kCharsetConverterManagerCID, &res);         if (NS_SUCCEEDED(res)) {          NS_IF_RELEASE(mDecoderDetected);          mDecoderDetected = nsnull;          res = ccm->GetUnicodeDecoder(&aCharsetDetected, &mDecoderDetected);          if (NS_SUCCEEDED(res)) {            decoder = mDecoderDetected;   // use detected charset instead          }        }      }    }  }  // update the total so far  mNumChars += inLength;  // Decoders are not available, do fallback  if (NULL == mDecoder && NULL == mDecoderDetected) {    *outBuffer = (char *) PR_Malloc(inLength+1);    if (NULL != *outBuffer) {      nsCRT::memcpy(*outBuffer, inBuffer, inLength);      *outLength = inLength;      (*outBuffer)[inLength] = '\0';      return 0;    }    return -1;  }  // do the conversion  PRUnichar *unichars;  PRInt32 unicharLength;  PRInt32 srcLen = inLength;  PRInt32 dstLength = 0;  char *dstPtr;  res = decoder->GetMaxLength(inBuffer, srcLen, &unicharLength);  // allocate temporary buffer to hold unicode string  unichars = new PRUnichar[unicharLength];  if (unichars == nsnull) {    res = NS_ERROR_OUT_OF_MEMORY;  }  else {    // convert to unicode    res = decoder->Convert(inBuffer, &srcLen, unichars, &unicharLength);    if (NS_SUCCEEDED(res)) {      res = encoder->GetMaxLength(unichars, unicharLength, &dstLength);      // allocale an output buffer      dstPtr = (char *) PR_Malloc(dstLength + 1);      if (dstPtr == nsnull) {        res = NS_ERROR_OUT_OF_MEMORY;      }      else {        PRInt32 buffLength = dstLength;        // convert from unicode        res = encoder->SetOutputErrorBehavior(nsIUnicodeEncoder::kOnError_Replace, nsnull, '?');        if (NS_SUCCEEDED(res)) {          res = encoder->Convert(unichars, &unicharLength, dstPtr, &dstLength);          if (NS_SUCCEEDED(res)) {            PRInt32 finLen = buffLength - dstLength;            res = encoder->Finish((char *)(dstPtr+dstLength), &finLen);            if (NS_SUCCEEDED(res)) {              dstLength += finLen;            }            dstPtr[dstLength] = '\0';            *outBuffer = dstPtr;       // set the result string            *outLength = dstLength;          }        }      }    }    delete [] unichars;  }  return NS_SUCCEEDED(res) ? 0 : -1;}