Bug 1255863 - Stop using nsTableEncoderSupport subclasses in GBK/GB18030 encoders. r=hsivonen
authorMasatoshi Kimura <VYV03354@nifty.ne.jp>
Wed, 06 Apr 2016 20:07:31 +0900
changeset 291875 38204fd2ece962c9504ae59d58c99bf38b5626bd
parent 291874 06d9d9cd6ab1187c284a46aa6830aa963d86456d
child 291876 a2fbcf1728cada53e5cb7c8e14537ba4b36461b0
push id74703
push userVYV03354@nifty.ne.jp
push dateWed, 06 Apr 2016 11:08:05 +0000
treeherdermozilla-inbound@38204fd2ece9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershsivonen
bugs1255863
milestone48.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1255863 - Stop using nsTableEncoderSupport subclasses in GBK/GB18030 encoders. r=hsivonen
intl/uconv/ucvcn/nsUnicodeToGBK.cpp
intl/uconv/ucvcn/nsUnicodeToGBK.h
--- a/intl/uconv/ucvcn/nsUnicodeToGBK.cpp
+++ b/intl/uconv/ucvcn/nsUnicodeToGBK.cpp
@@ -12,76 +12,55 @@
  * 04/Oct/1999. Yueheng Xu: used table gUnicodeToGBKTable[0x5200] to make 
  *              Unicode to GB mapping fast 
  */
 
 #include "nsUnicodeToGBK.h"
 #include "gbku.h"
 #include "uconvutil.h"
 #include "nsCharTraits.h"
+#include "nsUnicodeEncodeHelper.h"
 
 //-------------------------------------------------------------
 // Global table initialization function defined in gbku.h
 //-------------------------------------------------------------
 
-//-----------------------------------------------------------------------
-//  Private class used by nsUnicodeToGB18030 and nsUnicodeToGB18030Font0
-//    nsUnicodeToGB18030Uniq2Bytes
-//-----------------------------------------------------------------------
 static const uint16_t g_uf_gb18030_2bytes[] = {
 #include "gb18030uniq2b.uf"
 };
-class nsUnicodeToGB18030Uniq2Bytes : public nsTableEncoderSupport
-{
-public: 
-  nsUnicodeToGB18030Uniq2Bytes() 
-    : nsTableEncoderSupport(u2BytesCharset,
-                            (uMappingTable*) &g_uf_gb18030_2bytes, 2) {}
-protected: 
-};
-//-----------------------------------------------------------------------
-//  Private class used by nsUnicodeToGB18030
-//    nsUnicodeTo4BytesGB18030
-//-----------------------------------------------------------------------
 static const uint16_t g_uf_gb18030_4bytes[] = {
 #include "gb180304bytes.uf"
 };
-class nsUnicodeTo4BytesGB18030 : public nsTableEncoderSupport
-{
-public: 
-  nsUnicodeTo4BytesGB18030()
-    : nsTableEncoderSupport(u4BytesGB18030Charset, 
-                             (uMappingTable*) &g_uf_gb18030_4bytes, 4) {}
-protected: 
-};
-//-----------------------------------------------------------------------
-//  Private class used by nsUnicodeToGBK
-//    nsUnicodeToGBKUniq
-//-----------------------------------------------------------------------
 static const uint16_t g_uf_gbk[] = {
 #include "gbkuniq.uf"
 };
-class nsUnicodeToGBKUniq : public nsTableEncoderSupport
-{
-public: 
-  nsUnicodeToGBKUniq()
-    : nsTableEncoderSupport(u1ByteCharset,
-                             (uMappingTable*) &g_uf_gbk, 1) {}
-protected: 
-};
 //-----------------------------------------------------------------------
 //  nsUnicodeToGB18030
 //-----------------------------------------------------------------------
-void nsUnicodeToGB18030::CreateExtensionEncoder()
+nsresult nsUnicodeToGB18030::TryExtensionEncoder(char16_t aChar,
+                                                 char* aOut,
+                                                 int32_t *aOutLen)
 {
-  mExtensionEncoder = new nsUnicodeToGB18030Uniq2Bytes();
+  int32_t len = 1;
+  return nsUnicodeEncodeHelper::ConvertByTable(
+    &aChar, &len, aOut, aOutLen, u2BytesCharset, nullptr,
+    (uMappingTable*) &g_uf_gb18030_2bytes);
 }
-void nsUnicodeToGB18030::Create4BytesEncoder()
+
+nsresult nsUnicodeToGB18030::Try4BytesEncoder(char16_t aChar,
+                                              char* aOut,
+                                              int32_t *aOutLen)
 {
-  m4BytesEncoder = new nsUnicodeTo4BytesGB18030();
+  int32_t len = 1;
+  nsresult res = nsUnicodeEncodeHelper::ConvertByTable(
+    &aChar, &len, aOut, aOutLen, u4BytesGB18030Charset, nullptr,
+    (uMappingTable*) &g_uf_gb18030_4bytes);
+  MOZ_ASSERT(NS_FAILED(res) || ((1 == len) && (4 == *aOutLen)),
+             "unexpect conversion length");
+  return res;
 }
 
 nsresult nsUnicodeToGB18030::EncodeSurrogate(char16_t aSurrogateHigh,
                                              char16_t aSurrogateLow,
                                              char* aOut,
                                              int32_t aDestLength,
                                              int32_t aBufferLength)
 {
@@ -108,74 +87,34 @@ nsresult nsUnicodeToGB18030::EncodeSurro
   }
   return NS_ERROR_UENC_NOMAPPING;
 }
 
 //----------------------------------------------------------------------
 // Class nsUnicodeToGBK [implementation]
 
 nsUnicodeToGBK::nsUnicodeToGBK(uint32_t aMaxLength) :
-  nsEncoderSupport(aMaxLength)
+  nsEncoderSupport(aMaxLength), mSurrogateHigh(0)
 {
-  mExtensionEncoder = nullptr;
-  m4BytesEncoder = nullptr;
-  mSurrogateHigh = 0;
-}
-void nsUnicodeToGBK::CreateExtensionEncoder()
-{
-  mExtensionEncoder = new nsUnicodeToGBKUniq();
-}
-void nsUnicodeToGBK::Create4BytesEncoder()
-{
-  m4BytesEncoder = nullptr;
 }
 
 nsresult nsUnicodeToGBK::TryExtensionEncoder(char16_t aChar,
                                              char* aOut,
                                              int32_t *aOutLen)
 {
-  if( NS_IS_HIGH_SURROGATE(aChar) ||
-      NS_IS_LOW_SURROGATE(aChar) )
-  {
-    // performance tune for surrogate characters
-    return NS_ERROR_UENC_NOMAPPING;
-  }
-  if(! mExtensionEncoder )
-    CreateExtensionEncoder();
-  if(mExtensionEncoder)
-  {
-    int32_t len = 1;
-    return mExtensionEncoder->Convert(&aChar, &len, aOut, aOutLen);
-  }
-  return NS_ERROR_UENC_NOMAPPING;
+  int32_t len = 1;
+  return nsUnicodeEncodeHelper::ConvertByTable(
+    &aChar, &len, aOut, aOutLen, u1ByteCharset, nullptr,
+    (uMappingTable*) &g_uf_gbk);
 }
 
-nsresult nsUnicodeToGBK::Try4BytesEncoder(
-  char16_t aChar,
-  char* aOut,
-  int32_t *aOutLen
-)
+nsresult nsUnicodeToGBK::Try4BytesEncoder(char16_t aChar,
+                                          char* aOut,
+                                          int32_t *aOutLen)
 {
-  if( NS_IS_HIGH_SURROGATE(aChar) ||
-      NS_IS_LOW_SURROGATE(aChar) )
-  {
-    // performance tune for surrogate characters
-    return NS_ERROR_UENC_NOMAPPING;
-  }
-  if(! m4BytesEncoder )
-    Create4BytesEncoder();
-  if(m4BytesEncoder)
-  {
-    int32_t len = 1;
-    nsresult res = NS_OK;
-    res = m4BytesEncoder->Convert(&aChar, &len, aOut, aOutLen);
-    NS_ASSERTION(NS_FAILED(res) || ((1 == len) && (4 == *aOutLen)),
-      "unexpect conversion length");
-    return res;
-  }
   return NS_ERROR_UENC_NOMAPPING;
 }
 
 nsresult nsUnicodeToGBK::EncodeSurrogate(char16_t aSurrogateHigh,
                                          char16_t aSurrogateLow,
                                          char* aOut,
                                          int32_t aDestLength,
                                          int32_t aBufferLength)
@@ -191,18 +130,22 @@ NS_IMETHODIMP nsUnicodeToGBK::ConvertNoB
   int32_t iSrcLength = 0;
   int32_t iDestLength = 0;
   char16_t unicode;
   nsresult res = NS_OK;
   while (iSrcLength < *aSrcLength )
   {
     unicode = *aSrc;
     //if unicode's hi byte has something, it is not ASCII, must be a GB
-    if(IS_ASCII(unicode))
-    {
+    if (IS_ASCII(unicode)) {
+      // make sure we still have 1 byte for output first
+      if (iDestLength >= *aDestLength) {
+        res = NS_OK_UENC_MOREOUTPUT;
+        break;
+      }
       // this is an ASCII
       *aDest = CAST_UNICHAR_TO_CHAR(*aSrc);
       aDest++; // increment 1 byte
       iDestLength +=1;
     } else {
       char byte1, byte2;
       if(mUtil.UnicodeToGBKChar( unicode, false, &byte1, &byte2))
       {
@@ -216,41 +159,46 @@ NS_IMETHODIMP nsUnicodeToGBK::ConvertNoB
         aDest[1] = byte2;
         aDest += 2;	// increment 2 bytes
         iDestLength +=2;
       } else {
         // Swapped character in GB18030-2005
         if (unicode == 0xE7C7) {
           unicode = 0x1E3F;
         }
-        int32_t aOutLen = 2;
         // we cannot map in the common mapping. Let's try to
         // call the delegated 2 byte converter for the gbk or gb18030
         // unique 2 byte mapping
-        res = TryExtensionEncoder(unicode, aDest, &aOutLen);
+        int32_t outLen = *aDestLength - iDestLength;
+        if (NS_IS_HIGH_SURROGATE(unicode) ||
+            NS_IS_LOW_SURROGATE(unicode)) {
+          // performance tune for surrogate characters
+          res = NS_ERROR_UENC_NOMAPPING;
+        } else {
+          res = TryExtensionEncoder(unicode, aDest, &outLen);
+        }
         if (res == NS_OK) {
-          iDestLength += aOutLen;
-          aDest += aOutLen;
+          iDestLength += outLen;
+          aDest += outLen;
         } else if (res == NS_OK_UENC_MOREOUTPUT) {
           break;
         } else {
           // we still cannot map. Let's try to
           // call the delegated GB18030 4 byte converter
-          aOutLen = 4;
           if( NS_IS_HIGH_SURROGATE(unicode) )
           {
             if((iSrcLength+1) < *aSrcLength ) {
               res = EncodeSurrogate(aSrc[0],aSrc[1], aDest,
                                     iDestLength, *aDestLength);
               if (res == NS_OK) {
                 // since we got a surrogate pair, we need to increment src.
                 iSrcLength++ ;
                 aSrc++;
-                iDestLength += aOutLen;
-                aDest += aOutLen;
+                iDestLength += 4;
+                aDest += 4;
               } else {
                 if (res == NS_ERROR_UENC_NOMAPPING) {
                   // only get a high surrogate, but not a low surrogate
                   iSrcLength++;   // include length of the unmapped character
                 }
                 break;
               }
             } else {
@@ -260,54 +208,49 @@ NS_IMETHODIMP nsUnicodeToGBK::ConvertNoB
             }
           } else {
             if( NS_IS_LOW_SURROGATE(unicode) )
             {
               if(NS_IS_HIGH_SURROGATE(mSurrogateHigh)) {
                 res = EncodeSurrogate(mSurrogateHigh, aSrc[0], aDest,
                                       iDestLength, *aDestLength);
                 if (res == NS_OK) {
-                  iDestLength += aOutLen;
-                  aDest += aOutLen;
+                  iDestLength += 4;
+                  aDest += 4;
                 } else {
                   if (res == NS_ERROR_UENC_NOMAPPING) {
                     // only get a high surrogate, but not a low surrogate
                     iSrcLength++;   // include length of the unmapped character
                   }
                   break;
                 }
               } else {
                 // only get a low surrogate, but not a low surrogate
                 res = NS_ERROR_UENC_NOMAPPING;
                 iSrcLength++;   // include length of the unmapped character
                 break;
               }
             } else {
-              res = Try4BytesEncoder(unicode, aDest, &aOutLen);
+              outLen = *aDestLength - iDestLength;
+              res = Try4BytesEncoder(unicode, aDest, &outLen);
               if (res == NS_OK) {
-                NS_ASSERTION((aOutLen == 4), "we should always generate 4 bytes here");
-                iDestLength += aOutLen;
-                aDest += aOutLen;
+                iDestLength += outLen;
+                aDest += outLen;
               } else {
                 if (res == NS_ERROR_UENC_NOMAPPING) {
                   iSrcLength++;   // include length of the unmapped character
                 }
                 break;
               }
             }
           }
         }
       }
     }
     iSrcLength++ ; // Each unicode char just count as one in char16_t string;
     mSurrogateHigh = 0;
     aSrc++;
-    if ( iDestLength >= (*aDestLength) && (iSrcLength < *aSrcLength) )
-    {
-      res = NS_OK_UENC_MOREOUTPUT;
-      break;
-    }
   }
 //afterwhileloop:
   *aDestLength = iDestLength;
   *aSrcLength = iSrcLength;
   return res;
 }
--- a/intl/uconv/ucvcn/nsUnicodeToGBK.h
+++ b/intl/uconv/ucvcn/nsUnicodeToGBK.h
@@ -35,38 +35,38 @@ protected:
 
   //--------------------------------------------------------------------
   // Subclassing of nsEncoderSupport class [declaration]
   NS_IMETHOD ConvertNoBuffNoErr(const char16_t * aSrc,
                                 int32_t * aSrcLength,
                                 char * aDest,
                                 int32_t * aDestLength);
 
-  virtual void CreateExtensionEncoder();
-  virtual void Create4BytesEncoder();
-
-  nsCOMPtr<nsIUnicodeEncoder> mExtensionEncoder;
-  nsCOMPtr<nsIUnicodeEncoder> m4BytesEncoder;
 protected:
   char16_t mSurrogateHigh;
   nsGBKConvUtil mUtil;
-  nsresult TryExtensionEncoder(char16_t aChar, char* aDest, int32_t* aOutLen);
-  nsresult Try4BytesEncoder(char16_t aChar, char* aDest, int32_t* aOutLen);
+  virtual nsresult TryExtensionEncoder(char16_t aChar, char* aDest,
+                                       int32_t* aOutLen);
+  virtual nsresult Try4BytesEncoder(char16_t aChar, char* aDest,
+                                    int32_t* aOutLen);
   virtual nsresult EncodeSurrogate(char16_t aSurrogateHigh,
                                    char16_t aSurrogateLow, char* aDest,
                                    int32_t aDestLength, int32_t aBufferLength);
 };
 
 class nsUnicodeToGB18030: public nsUnicodeToGBK
 {
 public:
   nsUnicodeToGB18030() : nsUnicodeToGBK(4) {}
   virtual ~nsUnicodeToGB18030() {}
 protected:
-  virtual void CreateExtensionEncoder();
-  virtual void Create4BytesEncoder();
+  virtual nsresult TryExtensionEncoder(char16_t aChar, char* aDest,
+                                       int32_t* aOutLen) override;
+  virtual nsresult Try4BytesEncoder(char16_t aChar, char* aDest,
+                                    int32_t* aOutLen) override;
   virtual nsresult EncodeSurrogate(char16_t aSurrogateHigh,
                                    char16_t aSurrogateLow, char* aDest,
-                                   int32_t aDestLength, int32_t aBufferLength);
+                                   int32_t aDestLength,
+                                   int32_t aBufferLength) override;
 };
 
 #endif /* nsUnicodeToGBK_h___ */