michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsUCSupport.h" michael@0: #include "nsUnicodeDecodeHelper.h" michael@0: #include "nsUnicodeEncodeHelper.h" michael@0: #include michael@0: michael@0: #define DEFAULT_BUFFER_CAPACITY 16 michael@0: michael@0: // XXX review the buffer growth limitation code michael@0: michael@0: //---------------------------------------------------------------------- michael@0: // Class nsBasicDecoderSupport [implementation] michael@0: michael@0: nsBasicDecoderSupport::nsBasicDecoderSupport() michael@0: : mErrBehavior(kOnError_Recover) michael@0: { michael@0: } michael@0: michael@0: nsBasicDecoderSupport::~nsBasicDecoderSupport() michael@0: { michael@0: } michael@0: michael@0: //---------------------------------------------------------------------- michael@0: // Interface nsISupports [implementation] michael@0: michael@0: #ifdef DEBUG michael@0: NS_IMPL_ISUPPORTS(nsBasicDecoderSupport, michael@0: nsIUnicodeDecoder, michael@0: nsIBasicDecoder) michael@0: #else michael@0: NS_IMPL_ISUPPORTS(nsBasicDecoderSupport, nsIUnicodeDecoder) michael@0: #endif michael@0: michael@0: //---------------------------------------------------------------------- michael@0: // Interface nsIUnicodeDecoder [implementation] michael@0: michael@0: void michael@0: nsBasicDecoderSupport::SetInputErrorBehavior(int32_t aBehavior) michael@0: { michael@0: NS_ABORT_IF_FALSE(aBehavior == kOnError_Recover || aBehavior == kOnError_Signal, michael@0: "Unknown behavior for SetInputErrorBehavior"); michael@0: mErrBehavior = aBehavior; michael@0: } michael@0: michael@0: char16_t michael@0: nsBasicDecoderSupport::GetCharacterForUnMapped() michael@0: { michael@0: return char16_t(0xfffd); // Unicode REPLACEMENT CHARACTER michael@0: } michael@0: michael@0: //---------------------------------------------------------------------- michael@0: // Class nsBufferDecoderSupport [implementation] michael@0: michael@0: nsBufferDecoderSupport::nsBufferDecoderSupport(uint32_t aMaxLengthFactor) michael@0: : nsBasicDecoderSupport(), michael@0: mMaxLengthFactor(aMaxLengthFactor) michael@0: { michael@0: mBufferCapacity = DEFAULT_BUFFER_CAPACITY; michael@0: mBuffer = new char[mBufferCapacity]; michael@0: michael@0: Reset(); michael@0: } michael@0: michael@0: nsBufferDecoderSupport::~nsBufferDecoderSupport() michael@0: { michael@0: delete [] mBuffer; michael@0: } michael@0: michael@0: void nsBufferDecoderSupport::FillBuffer(const char ** aSrc, int32_t aSrcLength) michael@0: { michael@0: int32_t bcr = std::min(mBufferCapacity - mBufferLength, aSrcLength); michael@0: memcpy(mBuffer + mBufferLength, *aSrc, bcr); michael@0: mBufferLength += bcr; michael@0: (*aSrc) += bcr; michael@0: } michael@0: michael@0: //---------------------------------------------------------------------- michael@0: // Subclassing of nsBasicDecoderSupport class [implementation] michael@0: michael@0: NS_IMETHODIMP nsBufferDecoderSupport::Convert(const char * aSrc, michael@0: int32_t * aSrcLength, michael@0: char16_t * aDest, michael@0: int32_t * aDestLength) michael@0: { michael@0: // we do all operations using pointers internally michael@0: const char * src = aSrc; michael@0: const char * srcEnd = aSrc + *aSrcLength; michael@0: char16_t * dest = aDest; michael@0: char16_t * destEnd = aDest + *aDestLength; michael@0: michael@0: int32_t bcr, bcw; // byte counts for read & write; michael@0: nsresult res = NS_OK; michael@0: michael@0: // do we have some residual data from the last conversion? michael@0: if (mBufferLength > 0) { michael@0: if (dest == destEnd) { michael@0: res = NS_OK_UDEC_MOREOUTPUT; michael@0: } else { michael@0: for (;;) { michael@0: // we need new data to add to the buffer michael@0: if (src == srcEnd) { michael@0: res = NS_OK_UDEC_MOREINPUT; michael@0: break; michael@0: } michael@0: michael@0: // fill that buffer michael@0: int32_t buffLen = mBufferLength; // initial buffer length michael@0: FillBuffer(&src, srcEnd - src); michael@0: michael@0: // convert that buffer michael@0: bcr = mBufferLength; michael@0: bcw = destEnd - dest; michael@0: res = ConvertNoBuff(mBuffer, &bcr, dest, &bcw); michael@0: dest += bcw; michael@0: michael@0: // Detect invalid input character michael@0: if (res == NS_ERROR_ILLEGAL_INPUT && mErrBehavior == kOnError_Signal) { michael@0: break; michael@0: } michael@0: michael@0: if ((res == NS_OK_UDEC_MOREINPUT) && (bcw == 0)) { michael@0: res = NS_ERROR_UNEXPECTED; michael@0: #if defined(DEBUG_yokoyama) || defined(DEBUG_ftang) michael@0: NS_ERROR("This should not happen. Internal buffer may be corrupted."); michael@0: #endif michael@0: break; michael@0: } else { michael@0: if (bcr < buffLen) { michael@0: // we didn't convert that residual data - unfill the buffer michael@0: src -= mBufferLength - buffLen; michael@0: mBufferLength = buffLen; michael@0: #if defined(DEBUG_yokoyama) || defined(DEBUG_ftang) michael@0: NS_ERROR("This should not happen. Internal buffer may be corrupted."); michael@0: #endif michael@0: } else { michael@0: // the buffer and some extra data was converted - unget the rest michael@0: src -= mBufferLength - bcr; michael@0: mBufferLength = 0; michael@0: res = NS_OK; michael@0: } michael@0: break; michael@0: } michael@0: } michael@0: } michael@0: } michael@0: michael@0: if (res == NS_OK) { michael@0: bcr = srcEnd - src; michael@0: bcw = destEnd - dest; michael@0: res = ConvertNoBuff(src, &bcr, dest, &bcw); michael@0: src += bcr; michael@0: dest += bcw; michael@0: michael@0: // if we have partial input, store it in our internal buffer. michael@0: if (res == NS_OK_UDEC_MOREINPUT) { michael@0: bcr = srcEnd - src; michael@0: // make sure buffer is large enough michael@0: if (bcr > mBufferCapacity) { michael@0: // somehow we got into an error state and the buffer is growing out michael@0: // of control michael@0: res = NS_ERROR_UNEXPECTED; michael@0: } else { michael@0: FillBuffer(&src, bcr); michael@0: } michael@0: } michael@0: } michael@0: michael@0: *aSrcLength -= srcEnd - src; michael@0: *aDestLength -= destEnd - dest; michael@0: return res; michael@0: } michael@0: michael@0: NS_IMETHODIMP nsBufferDecoderSupport::Reset() michael@0: { michael@0: mBufferLength = 0; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP nsBufferDecoderSupport::GetMaxLength(const char* aSrc, michael@0: int32_t aSrcLength, michael@0: int32_t* aDestLength) michael@0: { michael@0: NS_ASSERTION(mMaxLengthFactor != 0, "Must override GetMaxLength!"); michael@0: *aDestLength = aSrcLength * mMaxLengthFactor; michael@0: return NS_OK; michael@0: } michael@0: michael@0: //---------------------------------------------------------------------- michael@0: // Class nsTableDecoderSupport [implementation] michael@0: michael@0: nsTableDecoderSupport::nsTableDecoderSupport(uScanClassID aScanClass, michael@0: uShiftInTable * aShiftInTable, michael@0: uMappingTable * aMappingTable, michael@0: uint32_t aMaxLengthFactor) michael@0: : nsBufferDecoderSupport(aMaxLengthFactor) michael@0: { michael@0: mScanClass = aScanClass; michael@0: mShiftInTable = aShiftInTable; michael@0: mMappingTable = aMappingTable; michael@0: } michael@0: michael@0: nsTableDecoderSupport::~nsTableDecoderSupport() michael@0: { michael@0: } michael@0: michael@0: //---------------------------------------------------------------------- michael@0: // Subclassing of nsBufferDecoderSupport class [implementation] michael@0: michael@0: NS_IMETHODIMP nsTableDecoderSupport::ConvertNoBuff(const char * aSrc, michael@0: int32_t * aSrcLength, michael@0: char16_t * aDest, michael@0: int32_t * aDestLength) michael@0: { michael@0: return nsUnicodeDecodeHelper::ConvertByTable(aSrc, aSrcLength, michael@0: aDest, aDestLength, michael@0: mScanClass, michael@0: mShiftInTable, mMappingTable, michael@0: mErrBehavior == kOnError_Signal); michael@0: } michael@0: michael@0: //---------------------------------------------------------------------- michael@0: // Class nsMultiTableDecoderSupport [implementation] michael@0: michael@0: nsMultiTableDecoderSupport::nsMultiTableDecoderSupport( michael@0: int32_t aTableCount, michael@0: const uRange * aRangeArray, michael@0: uScanClassID * aScanClassArray, michael@0: uMappingTable ** aMappingTable, michael@0: uint32_t aMaxLengthFactor) michael@0: : nsBufferDecoderSupport(aMaxLengthFactor) michael@0: { michael@0: mTableCount = aTableCount; michael@0: mRangeArray = aRangeArray; michael@0: mScanClassArray = aScanClassArray; michael@0: mMappingTable = aMappingTable; michael@0: } michael@0: michael@0: nsMultiTableDecoderSupport::~nsMultiTableDecoderSupport() michael@0: { michael@0: } michael@0: michael@0: //---------------------------------------------------------------------- michael@0: // Subclassing of nsBufferDecoderSupport class [implementation] michael@0: michael@0: NS_IMETHODIMP nsMultiTableDecoderSupport::ConvertNoBuff(const char * aSrc, michael@0: int32_t * aSrcLength, michael@0: char16_t * aDest, michael@0: int32_t * aDestLength) michael@0: { michael@0: return nsUnicodeDecodeHelper::ConvertByMultiTable(aSrc, aSrcLength, michael@0: aDest, aDestLength, michael@0: mTableCount, mRangeArray, michael@0: mScanClassArray, michael@0: mMappingTable, michael@0: mErrBehavior == kOnError_Signal); michael@0: } michael@0: michael@0: //---------------------------------------------------------------------- michael@0: // Class nsOneByteDecoderSupport [implementation] michael@0: michael@0: nsOneByteDecoderSupport::nsOneByteDecoderSupport( michael@0: uMappingTable * aMappingTable) michael@0: : nsBasicDecoderSupport() michael@0: , mMappingTable(aMappingTable) michael@0: , mFastTableCreated(false) michael@0: , mFastTableMutex("nsOneByteDecoderSupport mFastTableMutex") michael@0: { michael@0: } michael@0: michael@0: nsOneByteDecoderSupport::~nsOneByteDecoderSupport() michael@0: { michael@0: } michael@0: michael@0: //---------------------------------------------------------------------- michael@0: // Subclassing of nsBasicDecoderSupport class [implementation] michael@0: michael@0: NS_IMETHODIMP nsOneByteDecoderSupport::Convert(const char * aSrc, michael@0: int32_t * aSrcLength, michael@0: char16_t * aDest, michael@0: int32_t * aDestLength) michael@0: { michael@0: if (!mFastTableCreated) { michael@0: // Probably better to make this non-lazy and get rid of the mutex michael@0: mozilla::MutexAutoLock autoLock(mFastTableMutex); michael@0: if (!mFastTableCreated) { michael@0: nsresult res = nsUnicodeDecodeHelper::CreateFastTable( michael@0: mMappingTable, mFastTable, ONE_BYTE_TABLE_SIZE); michael@0: if (NS_FAILED(res)) return res; michael@0: mFastTableCreated = true; michael@0: } michael@0: } michael@0: michael@0: return nsUnicodeDecodeHelper::ConvertByFastTable(aSrc, aSrcLength, michael@0: aDest, aDestLength, michael@0: mFastTable, michael@0: ONE_BYTE_TABLE_SIZE, michael@0: mErrBehavior == kOnError_Signal); michael@0: } michael@0: michael@0: NS_IMETHODIMP nsOneByteDecoderSupport::GetMaxLength(const char * aSrc, michael@0: int32_t aSrcLength, michael@0: int32_t * aDestLength) michael@0: { michael@0: // single byte to Unicode converter michael@0: *aDestLength = aSrcLength; michael@0: return NS_OK_UDEC_EXACTLENGTH; michael@0: } michael@0: michael@0: NS_IMETHODIMP nsOneByteDecoderSupport::Reset() michael@0: { michael@0: // nothing to reset, no internal state in this case michael@0: return NS_OK; michael@0: } michael@0: michael@0: //---------------------------------------------------------------------- michael@0: // Class nsBasicEncoder [implementation] michael@0: nsBasicEncoder::nsBasicEncoder() michael@0: { michael@0: } michael@0: michael@0: nsBasicEncoder::~nsBasicEncoder() michael@0: { michael@0: } michael@0: michael@0: //---------------------------------------------------------------------- michael@0: // Interface nsISupports [implementation] michael@0: michael@0: NS_IMPL_ADDREF(nsBasicEncoder) michael@0: NS_IMPL_RELEASE(nsBasicEncoder) michael@0: #ifdef DEBUG michael@0: NS_IMPL_QUERY_INTERFACE(nsBasicEncoder, michael@0: nsIUnicodeEncoder, michael@0: nsIBasicEncoder) michael@0: #else michael@0: NS_IMPL_QUERY_INTERFACE(nsBasicEncoder, michael@0: nsIUnicodeEncoder) michael@0: #endif michael@0: //---------------------------------------------------------------------- michael@0: // Class nsEncoderSupport [implementation] michael@0: michael@0: nsEncoderSupport::nsEncoderSupport(uint32_t aMaxLengthFactor) : michael@0: mMaxLengthFactor(aMaxLengthFactor) michael@0: { michael@0: mBufferCapacity = DEFAULT_BUFFER_CAPACITY; michael@0: mBuffer = new char[mBufferCapacity]; michael@0: michael@0: mErrBehavior = kOnError_Signal; michael@0: mErrChar = 0; michael@0: michael@0: Reset(); michael@0: } michael@0: michael@0: nsEncoderSupport::~nsEncoderSupport() michael@0: { michael@0: delete [] mBuffer; michael@0: } michael@0: michael@0: NS_IMETHODIMP nsEncoderSupport::ConvertNoBuff(const char16_t * aSrc, michael@0: int32_t * aSrcLength, michael@0: char * aDest, michael@0: int32_t * aDestLength) michael@0: { michael@0: // we do all operations using pointers internally michael@0: const char16_t * src = aSrc; michael@0: const char16_t * srcEnd = aSrc + *aSrcLength; michael@0: char * dest = aDest; michael@0: char * destEnd = aDest + *aDestLength; michael@0: michael@0: int32_t bcr, bcw; // byte counts for read & write; michael@0: nsresult res; michael@0: michael@0: for (;;) { michael@0: bcr = srcEnd - src; michael@0: bcw = destEnd - dest; michael@0: res = ConvertNoBuffNoErr(src, &bcr, dest, &bcw); michael@0: src += bcr; michael@0: dest += bcw; michael@0: michael@0: if (res == NS_ERROR_UENC_NOMAPPING) { michael@0: if (mErrBehavior == kOnError_Replace) { michael@0: const char16_t buff[] = {mErrChar}; michael@0: bcr = 1; michael@0: bcw = destEnd - dest; michael@0: src--; // back the input: maybe the guy won't consume consume anything. michael@0: res = ConvertNoBuffNoErr(buff, &bcr, dest, &bcw); michael@0: src += bcr; michael@0: dest += bcw; michael@0: if (res != NS_OK) break; michael@0: } else if (mErrBehavior == kOnError_CallBack) { michael@0: bcw = destEnd - dest; michael@0: src--; michael@0: res = mErrEncoder->Convert(*src, dest, &bcw); michael@0: dest += bcw; michael@0: // if enought output space then the last char was used michael@0: if (res != NS_OK_UENC_MOREOUTPUT) src++; michael@0: if (res != NS_OK) break; michael@0: } else break; michael@0: } michael@0: else break; michael@0: } michael@0: michael@0: *aSrcLength -= srcEnd - src; michael@0: *aDestLength -= destEnd - dest; michael@0: return res; michael@0: } michael@0: michael@0: NS_IMETHODIMP nsEncoderSupport::FinishNoBuff(char * aDest, michael@0: int32_t * aDestLength) michael@0: { michael@0: *aDestLength = 0; michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult nsEncoderSupport::FlushBuffer(char ** aDest, const char * aDestEnd) michael@0: { michael@0: int32_t bcr, bcw; // byte counts for read & write; michael@0: nsresult res = NS_OK; michael@0: char * dest = *aDest; michael@0: michael@0: if (mBufferStart < mBufferEnd) { michael@0: bcr = mBufferEnd - mBufferStart; michael@0: bcw = aDestEnd - dest; michael@0: if (bcw < bcr) bcr = bcw; michael@0: memcpy(dest, mBufferStart, bcr); michael@0: dest += bcr; michael@0: mBufferStart += bcr; michael@0: michael@0: if (mBufferStart < mBufferEnd) res = NS_OK_UENC_MOREOUTPUT; michael@0: } michael@0: michael@0: *aDest = dest; michael@0: return res; michael@0: } michael@0: michael@0: michael@0: //---------------------------------------------------------------------- michael@0: // Interface nsIUnicodeEncoder [implementation] michael@0: michael@0: NS_IMETHODIMP nsEncoderSupport::Convert(const char16_t * aSrc, michael@0: int32_t * aSrcLength, michael@0: char * aDest, michael@0: int32_t * aDestLength) michael@0: { michael@0: // we do all operations using pointers internally michael@0: const char16_t * src = aSrc; michael@0: const char16_t * srcEnd = aSrc + *aSrcLength; michael@0: char * dest = aDest; michael@0: char * destEnd = aDest + *aDestLength; michael@0: michael@0: int32_t bcr, bcw; // byte counts for read & write; michael@0: nsresult res; michael@0: michael@0: res = FlushBuffer(&dest, destEnd); michael@0: if (res == NS_OK_UENC_MOREOUTPUT) goto final; michael@0: michael@0: bcr = srcEnd - src; michael@0: bcw = destEnd - dest; michael@0: res = ConvertNoBuff(src, &bcr, dest, &bcw); michael@0: src += bcr; michael@0: dest += bcw; michael@0: if ((res == NS_OK_UENC_MOREOUTPUT) && (dest < destEnd)) { michael@0: // convert exactly one character into the internal buffer michael@0: // at this point, there should be at least a char in the input michael@0: for (;;) { michael@0: bcr = 1; michael@0: bcw = mBufferCapacity; michael@0: res = ConvertNoBuff(src, &bcr, mBuffer, &bcw); michael@0: michael@0: if (res == NS_OK_UENC_MOREOUTPUT) { michael@0: delete [] mBuffer; michael@0: mBufferCapacity *= 2; michael@0: mBuffer = new char [mBufferCapacity]; michael@0: } else { michael@0: src += bcr; michael@0: mBufferStart = mBufferEnd = mBuffer; michael@0: mBufferEnd += bcw; michael@0: break; michael@0: } michael@0: } michael@0: michael@0: res = FlushBuffer(&dest, destEnd); michael@0: } michael@0: michael@0: final: michael@0: *aSrcLength -= srcEnd - src; michael@0: *aDestLength -= destEnd - dest; michael@0: return res; michael@0: } michael@0: michael@0: NS_IMETHODIMP nsEncoderSupport::Finish(char * aDest, int32_t * aDestLength) michael@0: { michael@0: // we do all operations using pointers internally michael@0: char * dest = aDest; michael@0: char * destEnd = aDest + *aDestLength; michael@0: michael@0: int32_t bcw; // byte count for write; michael@0: nsresult res; michael@0: michael@0: res = FlushBuffer(&dest, destEnd); michael@0: if (res == NS_OK_UENC_MOREOUTPUT) goto final; michael@0: michael@0: // do the finish into the internal buffer. michael@0: for (;;) { michael@0: bcw = mBufferCapacity; michael@0: res = FinishNoBuff(mBuffer, &bcw); michael@0: michael@0: if (res == NS_OK_UENC_MOREOUTPUT) { michael@0: delete [] mBuffer; michael@0: mBufferCapacity *= 2; michael@0: mBuffer = new char [mBufferCapacity]; michael@0: } else { michael@0: mBufferStart = mBufferEnd = mBuffer; michael@0: mBufferEnd += bcw; michael@0: break; michael@0: } michael@0: } michael@0: michael@0: res = FlushBuffer(&dest, destEnd); michael@0: michael@0: final: michael@0: *aDestLength -= destEnd - dest; michael@0: return res; michael@0: } michael@0: michael@0: NS_IMETHODIMP nsEncoderSupport::Reset() michael@0: { michael@0: mBufferStart = mBufferEnd = mBuffer; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP nsEncoderSupport::SetOutputErrorBehavior( michael@0: int32_t aBehavior, michael@0: nsIUnicharEncoder * aEncoder, michael@0: char16_t aChar) michael@0: { michael@0: if (aBehavior == kOnError_CallBack && !aEncoder) michael@0: return NS_ERROR_NULL_POINTER; michael@0: michael@0: mErrEncoder = aEncoder; michael@0: mErrBehavior = aBehavior; michael@0: mErrChar = aChar; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsEncoderSupport::GetMaxLength(const char16_t * aSrc, michael@0: int32_t aSrcLength, michael@0: int32_t * aDestLength) michael@0: { michael@0: *aDestLength = aSrcLength * mMaxLengthFactor; michael@0: return NS_OK; michael@0: } michael@0: michael@0: michael@0: //---------------------------------------------------------------------- michael@0: // Class nsTableEncoderSupport [implementation] michael@0: michael@0: nsTableEncoderSupport::nsTableEncoderSupport(uScanClassID aScanClass, michael@0: uShiftOutTable * aShiftOutTable, michael@0: uMappingTable * aMappingTable, michael@0: uint32_t aMaxLengthFactor) michael@0: : nsEncoderSupport(aMaxLengthFactor) michael@0: { michael@0: mScanClass = aScanClass; michael@0: mShiftOutTable = aShiftOutTable, michael@0: mMappingTable = aMappingTable; michael@0: } michael@0: michael@0: nsTableEncoderSupport::nsTableEncoderSupport(uScanClassID aScanClass, michael@0: uMappingTable * aMappingTable, michael@0: uint32_t aMaxLengthFactor) michael@0: : nsEncoderSupport(aMaxLengthFactor) michael@0: { michael@0: mScanClass = aScanClass; michael@0: mShiftOutTable = nullptr; michael@0: mMappingTable = aMappingTable; michael@0: } michael@0: michael@0: nsTableEncoderSupport::~nsTableEncoderSupport() michael@0: { michael@0: } michael@0: michael@0: //---------------------------------------------------------------------- michael@0: // Subclassing of nsEncoderSupport class [implementation] michael@0: michael@0: NS_IMETHODIMP nsTableEncoderSupport::ConvertNoBuffNoErr( michael@0: const char16_t * aSrc, michael@0: int32_t * aSrcLength, michael@0: char * aDest, michael@0: int32_t * aDestLength) michael@0: { michael@0: return nsUnicodeEncodeHelper::ConvertByTable(aSrc, aSrcLength, michael@0: aDest, aDestLength, michael@0: mScanClass, michael@0: mShiftOutTable, mMappingTable); michael@0: } michael@0: michael@0: //---------------------------------------------------------------------- michael@0: // Class nsMultiTableEncoderSupport [implementation] michael@0: michael@0: nsMultiTableEncoderSupport::nsMultiTableEncoderSupport( michael@0: int32_t aTableCount, michael@0: uScanClassID * aScanClassArray, michael@0: uShiftOutTable ** aShiftOutTable, michael@0: uMappingTable ** aMappingTable, michael@0: uint32_t aMaxLengthFactor) michael@0: : nsEncoderSupport(aMaxLengthFactor) michael@0: { michael@0: mTableCount = aTableCount; michael@0: mScanClassArray = aScanClassArray; michael@0: mShiftOutTable = aShiftOutTable; michael@0: mMappingTable = aMappingTable; michael@0: } michael@0: michael@0: nsMultiTableEncoderSupport::~nsMultiTableEncoderSupport() michael@0: { michael@0: } michael@0: michael@0: //---------------------------------------------------------------------- michael@0: // Subclassing of nsEncoderSupport class [implementation] michael@0: michael@0: NS_IMETHODIMP nsMultiTableEncoderSupport::ConvertNoBuffNoErr( michael@0: const char16_t * aSrc, michael@0: int32_t * aSrcLength, michael@0: char * aDest, michael@0: int32_t * aDestLength) michael@0: { michael@0: return nsUnicodeEncodeHelper::ConvertByMultiTable(aSrc, aSrcLength, michael@0: aDest, aDestLength, michael@0: mTableCount, michael@0: mScanClassArray, michael@0: mShiftOutTable, michael@0: mMappingTable); michael@0: }