NS_IMETHODIMP nsSaveAsCharset::Convert(const PRUnichar *inString, char **_retval) { if (nullptr == _retval) return NS_ERROR_NULL_POINTER; if (nullptr == inString) return NS_ERROR_NULL_POINTER; if (0 == *inString) return NS_ERROR_ILLEGAL_VALUE; nsresult rv = NS_OK; NS_ASSERTION(mEncoder, "need to call Init() before Convert()"); NS_ENSURE_TRUE(mEncoder, NS_ERROR_FAILURE); *_retval = nullptr; // make sure to start from the first charset in the list if (mCharsetListIndex > 0) { mCharsetListIndex = -1; rv = SetupUnicodeEncoder(GetNextCharset()); NS_ENSURE_SUCCESS(rv, rv); } do { // fallback to the next charset in the list if the last conversion failed by an unmapped character if (MASK_CHARSET_FALLBACK(mAttribute) && NS_ERROR_UENC_NOMAPPING == rv) { const char * charset = GetNextCharset(); if (!charset) break; rv = SetupUnicodeEncoder(charset); NS_ENSURE_SUCCESS(rv, rv); PR_FREEIF(*_retval); } if (attr_EntityBeforeCharsetConv == MASK_ENTITY(mAttribute)) { NS_ASSERTION(mEntityConverter, "need to call Init() before Convert()"); NS_ENSURE_TRUE(mEntityConverter, NS_ERROR_FAILURE); PRUnichar *entity = nullptr; // do the entity conversion first rv = mEntityConverter->ConvertToEntities(inString, mEntityVersion, &entity); if(NS_SUCCEEDED(rv)) { rv = DoCharsetConversion(entity, _retval); nsMemory::Free(entity); } } else rv = DoCharsetConversion(inString, _retval); } while (MASK_CHARSET_FALLBACK(mAttribute) && NS_ERROR_UENC_NOMAPPING == rv); return rv; }
NS_IMETHODIMP nsSaveAsCharset::Init(const char *charset, uint32_t attr, uint32_t entityVersion) { nsresult rv = NS_OK; mAttribute = attr; mEntityVersion = entityVersion; rv = SetupCharsetList(charset); NS_ENSURE_SUCCESS(rv, rv); // set up unicode encoder rv = SetupUnicodeEncoder(GetNextCharset()); NS_ENSURE_SUCCESS(rv, rv); // set up entity converter if (attr_EntityNone != MASK_ENTITY(mAttribute) && !mEntityConverter) mEntityConverter = do_CreateInstance(NS_ENTITYCONVERTER_CONTRACTID, &rv); return rv; }