Bug 1363281 - add UTF-7 support for IMAP. r=jcranmer
authorJorg K <jorgk@jorgk.com>
Wed, 14 Jun 2017 08:01:23 +0200
changeset 28338 ac30eed3d7e54d44f6824d9da864d3a89579e76c
parent 28337 f558febc1ead57c76ba5eb5af4443a67680f7fa4
child 28339 6e8cb90569125b04aadbb9f34c2ecc560c07837b
push id1986
push userclokep@gmail.com
push dateWed, 02 Aug 2017 14:43:31 +0000
treeherdercomm-beta@b51c9adf2c9e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjcranmer
bugs1363281
Bug 1363281 - add UTF-7 support for IMAP. r=jcranmer
mailnews/base/util/nsMsgI18N.cpp
mailnews/base/util/nsMsgI18N.h
mailnews/intl/nsUTF7ToUnicode.cpp
mailnews/intl/nsUTF7ToUnicode.h
mailnews/intl/nsUnicodeToUTF7.cpp
mailnews/intl/nsUnicodeToUTF7.h
--- 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.