Bug 1363281 - add UTF-7 support for IMAP. r=jcranmer
--- a/mailnews/base/util/nsMsgI18N.cpp
+++ b/mailnews/base/util/nsMsgI18N.cpp
@@ -21,16 +21,19 @@
#include "prmem.h"
#include "plstr.h"
#include "nsUTF8Utils.h"
#include "nsNetUtil.h"
#include "nsCRTGlue.h"
#include "nsComponentManagerUtils.h"
#include "nsUnicharUtils.h"
#include "nsIFileStreams.h"
+#include "../../intl/nsMUTF7ToUnicode.h"
+#include "../../intl/nsUnicodeToMUTF7.h"
+
//
// International functions necessary for composition
//
nsresult nsMsgI18NConvertFromUnicode(const char* aCharset,
const nsString& inString,
nsACString& outString,
bool aReportUencNoMapping)
@@ -74,16 +77,53 @@ nsresult nsMsgI18NConvertToUnicode(const
auto encoding = mozilla::Encoding::ForLabelNoReplacement(nsDependentCString(aCharset));
if (!encoding)
return NS_ERROR_UCONV_NOCONV;
return encoding->DecodeWithoutBOMHandlingAndWithoutReplacement(inString,
outString);
}
+nsresult CopyUTF16toMUTF7(const nsString &aSrc, nsACString& aDest)
+{
+ #define IMAP_UTF7_BUF_LENGTH 100
+ nsUnicodeToMUTF7 converter;
+ static char buffer[IMAP_UTF7_BUF_LENGTH];
+ char16_t *in = (char16_t *)aSrc.get();
+ int32_t inLen = aSrc.Length();
+ int32_t outLen;
+ aDest.Truncate();
+ while (inLen > 0) {
+ outLen = IMAP_UTF7_BUF_LENGTH;
+ int32_t remaining = inLen;
+ converter.ConvertNoBuffNoErr(in, &remaining, buffer, &outLen);
+ aDest.Append(buffer, outLen);
+ in += remaining;
+ inLen -= remaining;
+ }
+ outLen = IMAP_UTF7_BUF_LENGTH;
+ converter.FinishNoBuff(buffer, &outLen);
+ if (outLen > 0)
+ aDest.Append(buffer, outLen);
+ return NS_OK;
+}
+
+nsresult CopyMUTF7toUTF16(const nsCString& aSrc, nsAString& aDest)
+{
+ // UTF-7 encoding size cannot be larger than the size in UTF-16.
+ nsMUTF7ToUnicode converter;
+ int32_t inLen = aSrc.Length();
+ int32_t outLen = inLen;
+ aDest.SetCapacity(outLen);
+ converter.ConvertNoBuff(aSrc.get(), &inLen, aDest.BeginWriting(), &outLen);
+ MOZ_ASSERT(inLen == aSrc.Length(), "UTF-7 should not produce a longer output");
+ aDest.SetLength(outLen);
+ return NS_OK;
+}
+
// Charset used by the file system.
const char * nsMsgI18NFileSystemCharset()
{
/* Get a charset used for the file. */
static nsAutoCString fileSystemCharset;
if (fileSystemCharset.IsEmpty())
{
--- a/mailnews/base/util/nsMsgI18N.h
+++ b/mailnews/base/util/nsMsgI18N.h
@@ -133,26 +133,19 @@ NS_MSG_BASE void nsMsgI18NConvertRawByte
*
* @param inString [IN] Input raw octets
* @param outString [OUT] Output UTF-8 string
*/
NS_MSG_BASE void nsMsgI18NConvertRawBytesToUTF8(const nsCString& inString,
const char* charset,
nsACString& outString);
-// inline forwarders to avoid littering with 'x-imap4-.....'
-inline nsresult CopyUTF16toMUTF7(const nsString &aSrc, nsACString& aDest)
-{
- return nsMsgI18NConvertFromUnicode("x-imap4-modified-utf7", aSrc, aDest);
-}
-
-inline nsresult CopyMUTF7toUTF16(const nsCString& aSrc, nsAString& aDest)
-{
- return nsMsgI18NConvertToUnicode("x-imap4-modified-utf7", aSrc, aDest);
-}
+// Convert between UTF-16 and modified UTF-7 used for IMAP.
+NS_MSG_BASE nsresult CopyUTF16toMUTF7(const nsString &aSrc, nsACString& aDest);
+NS_MSG_BASE nsresult CopyMUTF7toUTF16(const nsCString& aSrc, nsAString& aDest);
inline nsresult ConvertToUnicode(const char* charset,
const nsCString &aSrc, nsAString& aDest)
{
return nsMsgI18NConvertToUnicode(charset, aSrc, aDest);
}
inline nsresult ConvertToUnicode(const char* charset,
--- a/mailnews/intl/nsUTF7ToUnicode.cpp
+++ b/mailnews/intl/nsUTF7ToUnicode.cpp
@@ -7,17 +7,16 @@
#define ENC_DIRECT 0
#define ENC_BASE64 1
//----------------------------------------------------------------------
// Class nsBasicUTF7Decoder [implementation]
nsBasicUTF7Decoder::nsBasicUTF7Decoder(char aLastChar, char aEscChar)
-: nsBufferDecoderSupport(1)
{
mLastChar = aLastChar;
mEscChar = aEscChar;
Reset();
}
nsresult nsBasicUTF7Decoder::DecodeDirect(
const char * aSrc,
@@ -211,17 +210,17 @@ NS_IMETHODIMP nsBasicUTF7Decoder::Conver
return res;
}
NS_IMETHODIMP nsBasicUTF7Decoder::Reset()
{
mEncoding = ENC_DIRECT;
mEncBits = 0;
mEncStep = 0;
- return nsBufferDecoderSupport::Reset();
+ return NS_OK;
}
//----------------------------------------------------------------------
// Class nsUTF7ToUnicode [implementation]
nsUTF7ToUnicode::nsUTF7ToUnicode()
: nsBasicUTF7Decoder('/', '+')
{
--- a/mailnews/intl/nsUTF7ToUnicode.h
+++ b/mailnews/intl/nsUTF7ToUnicode.h
@@ -11,24 +11,26 @@
// Class nsBasicUTF7Decoder [declaration]
/**
* Basic class for a character set converter from UTF-7 to Unicode.
*
* @created 03/Jun/1999
* @author Catalin Rotaru [CATA]
*/
-class nsBasicUTF7Decoder : public nsBufferDecoderSupport
+class nsBasicUTF7Decoder
{
public:
/**
* Class constructor.
*/
nsBasicUTF7Decoder(char aLastChar, char aEscChar);
+ NS_IMETHOD ConvertNoBuff(const char * aSrc, int32_t * aSrcLength,
+ char16_t * aDest, int32_t * aDestLength);
protected:
int32_t mEncoding; // current encoding
uint32_t mEncBits;
int32_t mEncStep;
char mLastChar;
char mEscChar;
@@ -38,18 +40,16 @@ protected:
char16_t * aDest, int32_t * aDestLength);
nsresult DecodeBase64(const char * aSrc, int32_t * aSrcLength,
char16_t * aDest, int32_t * aDestLength);
uint32_t CharToValue(char aChar);
//--------------------------------------------------------------------
// Subclassing of nsBufferDecoderSupport class [declaration]
- NS_IMETHOD ConvertNoBuff(const char * aSrc, int32_t * aSrcLength,
- char16_t * aDest, int32_t * aDestLength);
NS_IMETHOD Reset();
};
//----------------------------------------------------------------------
// Class nsUTF7ToUnicode [declaration]
/**
* A character set converter from Modified UTF7 to Unicode.
--- a/mailnews/intl/nsUnicodeToUTF7.cpp
+++ b/mailnews/intl/nsUnicodeToUTF7.cpp
@@ -11,17 +11,16 @@
#define ENC_DIRECT 0
#define ENC_BASE64 1
//----------------------------------------------------------------------
// Class nsBasicUTF7Encoder [implementation]
nsBasicUTF7Encoder::nsBasicUTF7Encoder(char aLastChar, char aEscChar)
-: nsEncoderSupport(5)
{
mLastChar = aLastChar;
mEscChar = aEscChar;
Reset();
}
nsresult nsBasicUTF7Encoder::ShiftEncoding(int32_t aEncoding,
char * aDest,
@@ -257,17 +256,17 @@ NS_IMETHODIMP nsBasicUTF7Encoder::Finish
return ShiftEncoding(ENC_DIRECT, aDest, aDestLength);
}
NS_IMETHODIMP nsBasicUTF7Encoder::Reset()
{
mEncoding = ENC_DIRECT;
mEncBits = 0;
mEncStep = 0;
- return nsEncoderSupport::Reset();
+ return NS_OK;
}
//----------------------------------------------------------------------
// Class nsUnicodeToUTF7 [implementation]
nsUnicodeToUTF7::nsUnicodeToUTF7()
: nsBasicUTF7Encoder('/', '+')
{
--- a/mailnews/intl/nsUnicodeToUTF7.h
+++ b/mailnews/intl/nsUnicodeToUTF7.h
@@ -10,24 +10,27 @@
// Class nsBasicUTF7Encoder [declaration]
/**
* Basic class for a character set converter from Unicode to UTF-7.
*
* @created 03/Jun/1999
* @author Catalin Rotaru [CATA]
*/
-class nsBasicUTF7Encoder : public nsEncoderSupport
+class nsBasicUTF7Encoder
{
public:
/**
* Class constructor.
*/
nsBasicUTF7Encoder(char aLastChar, char aEscChar);
+ NS_IMETHOD ConvertNoBuffNoErr(const char16_t * aSrc, int32_t * aSrcLength,
+ char * aDest, int32_t * aDestLength);
+ NS_IMETHOD FinishNoBuff(char * aDest, int32_t * aDestLength);
protected:
int32_t mEncoding; // current encoding
uint32_t mEncBits;
int32_t mEncStep;
char mLastChar;
char mEscChar;
@@ -39,19 +42,16 @@ protected:
nsresult EncodeBase64(const char16_t * aSrc, int32_t * aSrcLength,
char * aDest, int32_t * aDestLength);
char ValueToChar(uint32_t aValue);
virtual bool DirectEncodable(char16_t aChar);
//--------------------------------------------------------------------
// Subclassing of nsEncoderSupport class [declaration]
- NS_IMETHOD ConvertNoBuffNoErr(const char16_t * aSrc, int32_t * aSrcLength,
- char * aDest, int32_t * aDestLength);
- NS_IMETHOD FinishNoBuff(char * aDest, int32_t * aDestLength);
NS_IMETHOD Reset();
};
//----------------------------------------------------------------------
// Class nsUnicodeToUTF7 [declaration]
/**
* A character set converter from Unicode to UTF-7.