LCOV - code coverage report
Current view: directory - intl/uconv/util - nsUCSupport.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 268 230 85.8 %
Date: 2012-06-02 Functions: 55 47 85.5 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is Mozilla Communicator client code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Pierre Phaneuf <pp@ludusdesign.com>
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      27                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #include "pratom.h"
      40                 : #include "nsAlgorithm.h"
      41                 : #include "nsIComponentManager.h"
      42                 : #include "nsUCSupport.h"
      43                 : #include "nsUnicodeDecodeHelper.h"
      44                 : #include "nsUnicodeEncodeHelper.h"
      45                 : 
      46                 : #define DEFAULT_BUFFER_CAPACITY 16
      47                 : 
      48                 : // XXX review the buffer growth limitation code
      49                 : 
      50                 : //----------------------------------------------------------------------
      51                 : // Class nsBasicDecoderSupport [implementation]
      52                 : 
      53           15552 : nsBasicDecoderSupport::nsBasicDecoderSupport()
      54           15552 :   : mErrBehavior(kOnError_Recover)
      55                 : {
      56           15552 : }
      57                 : 
      58           15552 : nsBasicDecoderSupport::~nsBasicDecoderSupport()
      59                 : {
      60           31104 : }
      61                 : 
      62                 : //----------------------------------------------------------------------
      63                 : // Interface nsISupports [implementation]
      64                 : 
      65                 : #ifdef NS_DEBUG
      66          171045 : NS_IMPL_THREADSAFE_ISUPPORTS2(nsBasicDecoderSupport,
      67                 :                               nsIUnicodeDecoder,
      68                 :                               nsIBasicDecoder)
      69                 : #else
      70                 : NS_IMPL_THREADSAFE_ISUPPORTS1(nsBasicDecoderSupport, nsIUnicodeDecoder)
      71                 : #endif
      72                 : 
      73                 : //----------------------------------------------------------------------
      74                 : // Interface nsIUnicodeDecoder [implementation]
      75                 : 
      76                 : void
      77            3878 : nsBasicDecoderSupport::SetInputErrorBehavior(PRInt32 aBehavior)
      78                 : {
      79            3878 :   NS_ABORT_IF_FALSE(aBehavior == kOnError_Recover || aBehavior == kOnError_Signal,
      80                 :                     "Unknown behavior for SetInputErrorBehavior");
      81            3878 :   mErrBehavior = aBehavior;
      82            3878 : }
      83                 : 
      84                 : PRUnichar
      85               0 : nsBasicDecoderSupport::GetCharacterForUnMapped()
      86                 : {
      87               0 :   return PRUnichar(0xfffd); // Unicode REPLACEMENT CHARACTER
      88                 : }
      89                 : 
      90                 : //----------------------------------------------------------------------
      91                 : // Class nsBufferDecoderSupport [implementation]
      92                 : 
      93            8886 : nsBufferDecoderSupport::nsBufferDecoderSupport(PRUint32 aMaxLengthFactor)
      94                 :   : nsBasicDecoderSupport(),
      95            8886 :     mMaxLengthFactor(aMaxLengthFactor)
      96                 : {
      97            8886 :   mBufferCapacity = DEFAULT_BUFFER_CAPACITY;
      98           17772 :   mBuffer = new char[mBufferCapacity];
      99                 : 
     100            8886 :   Reset();
     101            8886 : }
     102                 : 
     103           17772 : nsBufferDecoderSupport::~nsBufferDecoderSupport()
     104                 : {
     105            8886 :   delete [] mBuffer;
     106           17772 : }
     107                 : 
     108            2374 : void nsBufferDecoderSupport::FillBuffer(const char ** aSrc, PRInt32 aSrcLength)
     109                 : {
     110            2374 :   PRInt32 bcr = NS_MIN(mBufferCapacity - mBufferLength, aSrcLength);
     111            2374 :   memcpy(mBuffer + mBufferLength, *aSrc, bcr);
     112            2374 :   mBufferLength += bcr;
     113            2374 :   (*aSrc) += bcr;
     114            2374 : }
     115                 : 
     116                 : //----------------------------------------------------------------------
     117                 : // Subclassing of nsBasicDecoderSupport class [implementation]
     118                 : 
     119          400611 : NS_IMETHODIMP nsBufferDecoderSupport::Convert(const char * aSrc,
     120                 :                                               PRInt32 * aSrcLength,
     121                 :                                               PRUnichar * aDest,
     122                 :                                               PRInt32 * aDestLength)
     123                 : {
     124                 :   // we do all operations using pointers internally
     125          400611 :   const char * src = aSrc;
     126          400611 :   const char * srcEnd = aSrc + *aSrcLength;
     127          400611 :   PRUnichar * dest = aDest;
     128          400611 :   PRUnichar * destEnd = aDest + *aDestLength;
     129                 : 
     130                 :   PRInt32 bcr, bcw; // byte counts for read & write;
     131          400611 :   nsresult res = NS_OK;
     132                 : 
     133                 :   // do we have some residual data from the last conversion?
     134          400611 :   if (mBufferLength > 0) {
     135            1243 :     if (dest == destEnd) {
     136               0 :       res = NS_OK_UDEC_MOREOUTPUT;
     137                 :     } else {
     138                 :       for (;;) {
     139                 :         // we need new data to add to the buffer
     140            1243 :         if (src == srcEnd) {
     141               0 :           res = NS_OK_UDEC_MOREINPUT;
     142               0 :           break;
     143                 :         }
     144                 : 
     145                 :         // fill that buffer
     146            1243 :         PRInt32 buffLen = mBufferLength;  // initial buffer length
     147            1243 :         FillBuffer(&src, srcEnd - src);
     148                 : 
     149                 :         // convert that buffer
     150            1243 :         bcr = mBufferLength;
     151            1243 :         bcw = destEnd - dest;
     152            1243 :         res = ConvertNoBuff(mBuffer, &bcr, dest, &bcw);
     153            1243 :         dest += bcw;
     154                 : 
     155                 :         // Detect invalid input character
     156            1243 :         if (res == NS_ERROR_ILLEGAL_INPUT && mErrBehavior == kOnError_Signal) {
     157               0 :           break;
     158                 :         }
     159                 : 
     160            1243 :         if ((res == NS_OK_UDEC_MOREINPUT) && (bcw == 0)) {
     161               2 :           res = NS_ERROR_UNEXPECTED;
     162                 : #if defined(DEBUG_yokoyama) || defined(DEBUG_ftang)
     163                 :           NS_ERROR("This should not happen. Internal buffer may be corrupted.");
     164                 : #endif
     165               2 :           break;
     166                 :         } else {
     167            1241 :           if (bcr < buffLen) {
     168                 :             // we didn't convert that residual data - unfill the buffer
     169             111 :             src -= mBufferLength - buffLen;
     170             111 :             mBufferLength = buffLen;
     171                 : #if defined(DEBUG_yokoyama) || defined(DEBUG_ftang)
     172                 :             NS_ERROR("This should not happen. Internal buffer may be corrupted.");
     173                 : #endif
     174                 :           } else {
     175                 :             // the buffer and some extra data was converted - unget the rest
     176            1130 :             src -= mBufferLength - bcr;
     177            1130 :             mBufferLength = 0;
     178            1130 :             res = NS_OK;
     179                 :           }
     180            1241 :           break;
     181                 :         }
     182                 :       }
     183                 :     }
     184                 :   }
     185                 : 
     186          400611 :   if (res == NS_OK) {
     187          400498 :     bcr = srcEnd - src;
     188          400498 :     bcw = destEnd - dest;
     189          400498 :     res = ConvertNoBuff(src, &bcr, dest, &bcw);
     190          400498 :     src += bcr;
     191          400498 :     dest += bcw;
     192                 : 
     193                 :     // if we have partial input, store it in our internal buffer.
     194          400498 :     if (res == NS_OK_UDEC_MOREINPUT) {
     195            1131 :       bcr = srcEnd - src;
     196                 :       // make sure buffer is large enough
     197            1131 :       if (bcr > mBufferCapacity) {
     198                 :           // somehow we got into an error state and the buffer is growing out
     199                 :           // of control
     200               0 :           res = NS_ERROR_UNEXPECTED;
     201                 :       } else {
     202            1131 :           FillBuffer(&src, bcr);
     203                 :       }
     204                 :     }
     205                 :   }
     206                 : 
     207          400611 :   *aSrcLength   -= srcEnd - src;
     208          400611 :   *aDestLength  -= destEnd - dest;
     209          400611 :   return res;
     210                 : }
     211                 : 
     212            9161 : NS_IMETHODIMP nsBufferDecoderSupport::Reset()
     213                 : {
     214            9161 :   mBufferLength = 0;
     215            9161 :   return NS_OK;
     216                 : }
     217                 : 
     218          400268 : NS_IMETHODIMP nsBufferDecoderSupport::GetMaxLength(const char* aSrc,
     219                 :                                                    PRInt32 aSrcLength,
     220                 :                                                    PRInt32* aDestLength)
     221                 : {
     222          400268 :   NS_ASSERTION(mMaxLengthFactor != 0, "Must override GetMaxLength!");
     223          400268 :   *aDestLength = aSrcLength * mMaxLengthFactor;
     224          400268 :   return NS_OK;
     225                 : }
     226                 : 
     227                 : //----------------------------------------------------------------------
     228                 : // Class nsTableDecoderSupport [implementation]
     229                 : 
     230               2 : nsTableDecoderSupport::nsTableDecoderSupport(uScanClassID aScanClass,
     231                 :                                              uShiftInTable * aShiftInTable,
     232                 :                                              uMappingTable  * aMappingTable,
     233                 :                                              PRUint32 aMaxLengthFactor)
     234               2 : : nsBufferDecoderSupport(aMaxLengthFactor)
     235                 : {
     236               2 :   mScanClass = aScanClass;
     237               2 :   mShiftInTable = aShiftInTable;
     238               2 :   mMappingTable = aMappingTable;
     239               2 : }
     240                 : 
     241               2 : nsTableDecoderSupport::~nsTableDecoderSupport()
     242                 : {
     243               4 : }
     244                 : 
     245                 : //----------------------------------------------------------------------
     246                 : // Subclassing of nsBufferDecoderSupport class [implementation]
     247                 : 
     248             263 : NS_IMETHODIMP nsTableDecoderSupport::ConvertNoBuff(const char * aSrc,
     249                 :                                                    PRInt32 * aSrcLength,
     250                 :                                                    PRUnichar * aDest,
     251                 :                                                    PRInt32 * aDestLength)
     252                 : {
     253                 :   return nsUnicodeDecodeHelper::ConvertByTable(aSrc, aSrcLength,
     254                 :                                                aDest, aDestLength,
     255                 :                                                mScanClass,
     256                 :                                                mShiftInTable, mMappingTable,
     257             263 :                                                mErrBehavior == kOnError_Signal);
     258                 : }
     259                 : 
     260                 : //----------------------------------------------------------------------
     261                 : // Class nsMultiTableDecoderSupport [implementation]
     262                 : 
     263            8852 : nsMultiTableDecoderSupport::nsMultiTableDecoderSupport(
     264                 :                             PRInt32 aTableCount,
     265                 :                             const uRange * aRangeArray,
     266                 :                             uScanClassID * aScanClassArray,
     267                 :                             uMappingTable ** aMappingTable,
     268                 :                             PRUint32 aMaxLengthFactor)
     269            8852 : : nsBufferDecoderSupport(aMaxLengthFactor)
     270                 : {
     271            8852 :   mTableCount = aTableCount;
     272            8852 :   mRangeArray = aRangeArray;
     273            8852 :   mScanClassArray = aScanClassArray;
     274            8852 :   mMappingTable = aMappingTable;
     275            8852 : }
     276                 : 
     277           17704 : nsMultiTableDecoderSupport::~nsMultiTableDecoderSupport()
     278                 : {
     279           35408 : }
     280                 : 
     281                 : //----------------------------------------------------------------------
     282                 : // Subclassing of nsBufferDecoderSupport class [implementation]
     283                 : 
     284          270081 : NS_IMETHODIMP nsMultiTableDecoderSupport::ConvertNoBuff(const char * aSrc,
     285                 :                                                         PRInt32 * aSrcLength,
     286                 :                                                         PRUnichar * aDest,
     287                 :                                                         PRInt32 * aDestLength)
     288                 : {
     289                 :   return nsUnicodeDecodeHelper::ConvertByMultiTable(aSrc, aSrcLength,
     290                 :                                                     aDest, aDestLength,
     291                 :                                                     mTableCount, mRangeArray,
     292                 :                                                     mScanClassArray,
     293                 :                                                     mMappingTable,
     294          270081 :                                                     mErrBehavior == kOnError_Signal);
     295                 : }
     296                 : 
     297                 : //----------------------------------------------------------------------
     298                 : // Class nsOneByteDecoderSupport [implementation]
     299                 : 
     300            1279 : nsOneByteDecoderSupport::nsOneByteDecoderSupport(
     301                 :                          uMappingTable  * aMappingTable)
     302                 :   : nsBasicDecoderSupport()
     303                 :   , mMappingTable(aMappingTable)
     304                 :   , mFastTableCreated(false)
     305            1279 :   , mFastTableMutex("nsOneByteDecoderSupport mFastTableMutex")
     306                 : {
     307            1279 : }
     308                 : 
     309            2558 : nsOneByteDecoderSupport::~nsOneByteDecoderSupport()
     310                 : {
     311            5116 : }
     312                 : 
     313                 : //----------------------------------------------------------------------
     314                 : // Subclassing of nsBasicDecoderSupport class [implementation]
     315                 : 
     316           98705 : NS_IMETHODIMP nsOneByteDecoderSupport::Convert(const char * aSrc,
     317                 :                                               PRInt32 * aSrcLength,
     318                 :                                               PRUnichar * aDest,
     319                 :                                               PRInt32 * aDestLength)
     320                 : {
     321           98705 :   if (!mFastTableCreated) {
     322                 :     // Probably better to make this non-lazy and get rid of the mutex
     323            1814 :     mozilla::MutexAutoLock autoLock(mFastTableMutex);
     324             907 :     if (!mFastTableCreated) {
     325                 :       nsresult res = nsUnicodeDecodeHelper::CreateFastTable(
     326             907 :                          mMappingTable, mFastTable, ONE_BYTE_TABLE_SIZE);
     327             907 :       if (NS_FAILED(res)) return res;
     328             907 :       mFastTableCreated = true;
     329                 :     }
     330                 :   }
     331                 : 
     332                 :   return nsUnicodeDecodeHelper::ConvertByFastTable(aSrc, aSrcLength,
     333                 :                                                    aDest, aDestLength,
     334                 :                                                    mFastTable,
     335                 :                                                    ONE_BYTE_TABLE_SIZE,
     336           98705 :                                                    mErrBehavior == kOnError_Signal);
     337                 : }
     338                 : 
     339            7790 : NS_IMETHODIMP nsOneByteDecoderSupport::GetMaxLength(const char * aSrc,
     340                 :                                                     PRInt32 aSrcLength,
     341                 :                                                     PRInt32 * aDestLength)
     342                 : {
     343                 :   // single byte to Unicode converter
     344            7790 :   *aDestLength = aSrcLength;
     345            7790 :   return NS_OK_UDEC_EXACTLENGTH;
     346                 : }
     347                 : 
     348               0 : NS_IMETHODIMP nsOneByteDecoderSupport::Reset()
     349                 : {
     350                 :   // nothing to reset, no internal state in this case
     351               0 :   return NS_OK;
     352                 : }
     353                 : 
     354                 : //----------------------------------------------------------------------
     355                 : // Class nsBasicEncoder [implementation]
     356            9929 : nsBasicEncoder::nsBasicEncoder()
     357                 : {
     358            9929 : }
     359                 : 
     360            9929 : nsBasicEncoder::~nsBasicEncoder()
     361                 : {
     362           19858 : }
     363                 : 
     364                 : //----------------------------------------------------------------------
     365                 : // Interface nsISupports [implementation]
     366                 : 
     367           49645 : NS_IMPL_ADDREF(nsBasicEncoder)
     368           49645 : NS_IMPL_RELEASE(nsBasicEncoder)
     369                 : #ifdef NS_DEBUG
     370           29787 : NS_IMPL_QUERY_INTERFACE2(nsBasicEncoder,
     371                 :                          nsIUnicodeEncoder,
     372                 :                          nsIBasicEncoder)
     373                 : #else
     374                 : NS_IMPL_QUERY_INTERFACE1(nsBasicEncoder,
     375                 :                          nsIUnicodeEncoder)
     376                 : #endif
     377                 : //----------------------------------------------------------------------
     378                 : // Class nsEncoderSupport [implementation]
     379                 : 
     380            9892 : nsEncoderSupport::nsEncoderSupport(PRUint32 aMaxLengthFactor) :
     381            9892 :   mMaxLengthFactor(aMaxLengthFactor)
     382                 : {
     383            9892 :   mBufferCapacity = DEFAULT_BUFFER_CAPACITY;
     384           19784 :   mBuffer = new char[mBufferCapacity];
     385                 : 
     386            9892 :   mErrBehavior = kOnError_Signal;
     387            9892 :   mErrChar = 0;
     388                 : 
     389            9892 :   Reset();
     390            9892 : }
     391                 : 
     392           19784 : nsEncoderSupport::~nsEncoderSupport()
     393                 : {
     394            9892 :   delete [] mBuffer;
     395           19784 : }
     396                 : 
     397          171846 : NS_IMETHODIMP nsEncoderSupport::ConvertNoBuff(const PRUnichar * aSrc,
     398                 :                                               PRInt32 * aSrcLength,
     399                 :                                               char * aDest,
     400                 :                                               PRInt32 * aDestLength)
     401                 : {
     402                 :   // we do all operations using pointers internally
     403          171846 :   const PRUnichar * src = aSrc;
     404          171846 :   const PRUnichar * srcEnd = aSrc + *aSrcLength;
     405          171846 :   char * dest = aDest;
     406          171846 :   char * destEnd = aDest + *aDestLength;
     407                 : 
     408                 :   PRInt32 bcr, bcw; // byte counts for read & write;
     409                 :   nsresult res;
     410                 : 
     411             119 :   for (;;) {
     412          171965 :     bcr = srcEnd - src;
     413          171965 :     bcw = destEnd - dest;
     414          171965 :     res = ConvertNoBuffNoErr(src, &bcr, dest, &bcw);
     415          171965 :     src += bcr;
     416          171965 :     dest += bcw;
     417                 : 
     418          171965 :     if (res == NS_ERROR_UENC_NOMAPPING) {
     419           12073 :       if (mErrBehavior == kOnError_Replace) {
     420             119 :         const PRUnichar buff[] = {mErrChar};
     421             119 :         bcr = 1;
     422             119 :         bcw = destEnd - dest;
     423             119 :         src--; // back the input: maybe the guy won't consume consume anything.
     424             119 :         res = ConvertNoBuffNoErr(buff, &bcr, dest, &bcw);
     425             119 :         src += bcr;
     426             119 :         dest += bcw;
     427             119 :         if (res != NS_OK) break;
     428           11954 :       } else if (mErrBehavior == kOnError_CallBack) {
     429               0 :         bcw = destEnd - dest;
     430               0 :         src--;
     431               0 :         res = mErrEncoder->Convert(*src, dest, &bcw);
     432               0 :         dest += bcw;
     433                 :         // if enought output space then the last char was used
     434               0 :         if (res != NS_OK_UENC_MOREOUTPUT) src++;
     435               0 :         if (res != NS_OK) break;
     436           11954 :       } else break;
     437                 :     }
     438          159892 :     else break;
     439                 :   }
     440                 : 
     441          171846 :   *aSrcLength   -= srcEnd - src;
     442          171846 :   *aDestLength  -= destEnd - dest;
     443          171846 :   return res;
     444                 : }
     445                 : 
     446          538137 : NS_IMETHODIMP nsEncoderSupport::FinishNoBuff(char * aDest,
     447                 :                                              PRInt32 * aDestLength)
     448                 : {
     449          538137 :   *aDestLength = 0;
     450          538137 :   return NS_OK;
     451                 : }
     452                 : 
     453         1378477 : nsresult nsEncoderSupport::FlushBuffer(char ** aDest, const char * aDestEnd)
     454                 : {
     455                 :   PRInt32 bcr, bcw; // byte counts for read & write;
     456         1378477 :   nsresult res = NS_OK;
     457         1378477 :   char * dest = *aDest;
     458                 : 
     459         1378477 :   if (mBufferStart < mBufferEnd) {
     460               6 :     bcr = mBufferEnd - mBufferStart;
     461               6 :     bcw = aDestEnd - dest;
     462               6 :     if (bcw < bcr) bcr = bcw;
     463               6 :     memcpy(dest, mBufferStart, bcr);
     464               6 :     dest += bcr;
     465               6 :     mBufferStart += bcr;
     466                 : 
     467               6 :     if (mBufferStart < mBufferEnd) res = NS_OK_UENC_MOREOUTPUT;
     468                 :   }
     469                 : 
     470         1378477 :   *aDest = dest;
     471         1378477 :   return res;
     472                 : }
     473                 : 
     474                 : 
     475                 : //----------------------------------------------------------------------
     476                 : // Interface nsIUnicodeEncoder [implementation]
     477                 : 
     478          171855 : NS_IMETHODIMP nsEncoderSupport::Convert(const PRUnichar * aSrc,
     479                 :                                         PRInt32 * aSrcLength,
     480                 :                                         char * aDest,
     481                 :                                         PRInt32 * aDestLength)
     482                 : {
     483                 :   // we do all operations using pointers internally
     484          171855 :   const PRUnichar * src = aSrc;
     485          171855 :   const PRUnichar * srcEnd = aSrc + *aSrcLength;
     486          171855 :   char * dest = aDest;
     487          171855 :   char * destEnd = aDest + *aDestLength;
     488                 : 
     489                 :   PRInt32 bcr, bcw; // byte counts for read & write;
     490                 :   nsresult res;
     491                 : 
     492          171855 :   res = FlushBuffer(&dest, destEnd);
     493          171855 :   if (res == NS_OK_UENC_MOREOUTPUT) goto final;
     494                 : 
     495          171855 :   bcr = srcEnd - src;
     496          171855 :   bcw = destEnd - dest;
     497          171855 :   res = ConvertNoBuff(src, &bcr, dest, &bcw);
     498          171855 :   src += bcr;
     499          171855 :   dest += bcw;
     500          171855 :   if ((res == NS_OK_UENC_MOREOUTPUT) && (dest < destEnd)) {
     501                 :     // convert exactly one character into the internal buffer
     502                 :     // at this point, there should be at least a char in the input
     503               0 :     for (;;) {
     504               0 :       bcr = 1;
     505               0 :       bcw = mBufferCapacity;
     506               0 :       res = ConvertNoBuff(src, &bcr, mBuffer, &bcw);
     507                 : 
     508               0 :       if (res == NS_OK_UENC_MOREOUTPUT) {
     509               0 :         delete [] mBuffer;
     510               0 :         mBufferCapacity *= 2;
     511               0 :         mBuffer = new char [mBufferCapacity];
     512                 :       } else {
     513               0 :         src += bcr;
     514               0 :         mBufferStart = mBufferEnd = mBuffer;
     515               0 :         mBufferEnd += bcw;
     516                 :         break;
     517                 :       }
     518                 :     }
     519                 : 
     520               0 :     res = FlushBuffer(&dest, destEnd);
     521                 :   }
     522                 : 
     523                 : final:
     524          171855 :   *aSrcLength   -= srcEnd - src;
     525          171855 :   *aDestLength  -= destEnd - dest;
     526          171855 :   return res;
     527                 : }
     528                 : 
     529          603311 : NS_IMETHODIMP nsEncoderSupport::Finish(char * aDest, PRInt32 * aDestLength)
     530                 : {
     531                 :   // we do all operations using pointers internally
     532          603311 :   char * dest = aDest;
     533          603311 :   char * destEnd = aDest + *aDestLength;
     534                 : 
     535                 :   PRInt32 bcw; // byte count for write;
     536                 :   nsresult res;
     537                 : 
     538          603311 :   res = FlushBuffer(&dest, destEnd);
     539          603311 :   if (res == NS_OK_UENC_MOREOUTPUT) goto final;
     540                 : 
     541                 :   // do the finish into the internal buffer.
     542               0 :   for (;;) {
     543          603311 :     bcw = mBufferCapacity;
     544          603311 :     res = FinishNoBuff(mBuffer, &bcw);
     545                 : 
     546          603311 :     if (res == NS_OK_UENC_MOREOUTPUT) {
     547               0 :       delete [] mBuffer;
     548               0 :       mBufferCapacity *= 2;
     549               0 :       mBuffer = new char [mBufferCapacity];
     550                 :     } else {
     551          603311 :       mBufferStart = mBufferEnd = mBuffer;
     552          603311 :       mBufferEnd += bcw;
     553                 :       break;
     554                 :     }
     555                 :   }
     556                 : 
     557          603311 :   res = FlushBuffer(&dest, destEnd);
     558                 : 
     559                 : final:
     560          603311 :   *aDestLength  -= destEnd - dest;
     561          603311 :   return res;
     562                 : }
     563                 : 
     564            9928 : NS_IMETHODIMP nsEncoderSupport::Reset()
     565                 : {
     566            9928 :   mBufferStart = mBufferEnd = mBuffer;
     567            9928 :   return NS_OK;
     568                 : }
     569                 : 
     570            9885 : NS_IMETHODIMP nsEncoderSupport::SetOutputErrorBehavior(
     571                 :                                 PRInt32 aBehavior,
     572                 :                                 nsIUnicharEncoder * aEncoder,
     573                 :                                 PRUnichar aChar)
     574                 : {
     575            9885 :   if (aBehavior == kOnError_CallBack && aEncoder == nsnull)
     576               0 :     return NS_ERROR_NULL_POINTER;
     577                 : 
     578            9885 :   mErrEncoder = aEncoder;
     579            9885 :   mErrBehavior = aBehavior;
     580            9885 :   mErrChar = aChar;
     581            9885 :   return NS_OK;
     582                 : }
     583                 : 
     584                 : NS_IMETHODIMP
     585            1180 : nsEncoderSupport::GetMaxLength(const PRUnichar * aSrc,
     586                 :                                PRInt32 aSrcLength,
     587                 :                                PRInt32 * aDestLength)
     588                 : {
     589            1180 :   *aDestLength = aSrcLength * mMaxLengthFactor;
     590            1180 :   return NS_OK;
     591                 : }
     592                 : 
     593                 : 
     594                 : //----------------------------------------------------------------------
     595                 : // Class nsTableEncoderSupport [implementation]
     596                 : 
     597             987 : nsTableEncoderSupport::nsTableEncoderSupport(uScanClassID aScanClass,
     598                 :                                              uShiftOutTable * aShiftOutTable,
     599                 :                                              uMappingTable  * aMappingTable,
     600                 :                                              PRUint32 aMaxLengthFactor)
     601             987 : : nsEncoderSupport(aMaxLengthFactor)
     602                 : {
     603             987 :   mScanClass = aScanClass;
     604                 :   mShiftOutTable = aShiftOutTable,
     605             987 :   mMappingTable = aMappingTable;
     606             987 : }
     607                 : 
     608               0 : nsTableEncoderSupport::nsTableEncoderSupport(uScanClassID aScanClass,
     609                 :                                              uMappingTable  * aMappingTable,
     610                 :                                              PRUint32 aMaxLengthFactor)
     611               0 : : nsEncoderSupport(aMaxLengthFactor)
     612                 : {
     613               0 :   mScanClass = aScanClass;
     614               0 :   mShiftOutTable = nsnull;
     615               0 :   mMappingTable = aMappingTable;
     616               0 : }
     617                 : 
     618            1974 : nsTableEncoderSupport::~nsTableEncoderSupport()
     619                 : {
     620            3948 : }
     621                 : 
     622                 : //----------------------------------------------------------------------
     623                 : // Subclassing of nsEncoderSupport class [implementation]
     624                 : 
     625          172041 : NS_IMETHODIMP nsTableEncoderSupport::ConvertNoBuffNoErr(
     626                 :                                      const PRUnichar * aSrc,
     627                 :                                      PRInt32 * aSrcLength,
     628                 :                                      char * aDest,
     629                 :                                      PRInt32 * aDestLength)
     630                 : {
     631                 :   return nsUnicodeEncodeHelper::ConvertByTable(aSrc, aSrcLength,
     632                 :                                                aDest, aDestLength,
     633                 :                                                mScanClass,
     634          172041 :                                                mShiftOutTable, mMappingTable);
     635                 : }
     636                 : 
     637                 : //----------------------------------------------------------------------
     638                 : // Class nsMultiTableEncoderSupport [implementation]
     639                 : 
     640            8851 : nsMultiTableEncoderSupport::nsMultiTableEncoderSupport(
     641                 :                             PRInt32 aTableCount,
     642                 :                             uScanClassID * aScanClassArray,
     643                 :                             uShiftOutTable ** aShiftOutTable,
     644                 :                             uMappingTable  ** aMappingTable,
     645                 :                             PRUint32 aMaxLengthFactor)
     646            8851 : : nsEncoderSupport(aMaxLengthFactor)
     647                 : {
     648            8851 :   mTableCount = aTableCount;
     649            8851 :   mScanClassArray = aScanClassArray;
     650            8851 :   mShiftOutTable = aShiftOutTable;
     651            8851 :   mMappingTable = aMappingTable;
     652            8851 : }
     653                 : 
     654           17702 : nsMultiTableEncoderSupport::~nsMultiTableEncoderSupport()
     655                 : {
     656           35404 : }
     657                 : 
     658                 : //----------------------------------------------------------------------
     659                 : // Subclassing of nsEncoderSupport class [implementation]
     660                 : 
     661               7 : NS_IMETHODIMP nsMultiTableEncoderSupport::ConvertNoBuffNoErr(
     662                 :                                           const PRUnichar * aSrc,
     663                 :                                           PRInt32 * aSrcLength,
     664                 :                                           char * aDest,
     665                 :                                           PRInt32 * aDestLength)
     666                 : {
     667                 :   return nsUnicodeEncodeHelper::ConvertByMultiTable(aSrc, aSrcLength,
     668                 :                                                     aDest, aDestLength,
     669                 :                                                     mTableCount,
     670                 :                                                     mScanClassArray,
     671                 :                                                     mShiftOutTable,
     672               7 :                                                     mMappingTable);
     673                 : }

Generated by: LCOV version 1.7