diff --git a/intl/uconv/ucvja2/nsISO2022JPToUnicode.cpp b/intl/uconv/ucvja2/nsISO2022JPToUnicode.cpp index d6e1c3cedf4..a89d182c8ff 100644 --- a/intl/uconv/ucvja2/nsISO2022JPToUnicode.cpp +++ b/intl/uconv/ucvja2/nsISO2022JPToUnicode.cpp @@ -17,41 +17,14 @@ * Netscape Communications Corporation. All Rights Reserved. */ -#include "pratom.h" #include "nsIComponentManager.h" #include "nsISO2022JPToUnicode.h" #include "nsUCVJA2Dll.h" //---------------------------------------------------------------------- -// Class nsISO2022JPToUnicode [implementation] +// Global functions and data [declaration] -NS_IMPL_ISUPPORTS(nsISO2022JPToUnicode, kIUnicodeDecoderIID); - -nsISO2022JPToUnicode::nsISO2022JPToUnicode() -{ - NS_INIT_REFCNT(); - PR_AtomicIncrement(&g_InstanceCount); - - mHelper = nsnull; - Reset(); -} - -nsISO2022JPToUnicode::~nsISO2022JPToUnicode() -{ - NS_IF_RELEASE(mHelper); - PR_AtomicDecrement(&g_InstanceCount); -} - -nsresult nsISO2022JPToUnicode::CreateInstance(nsISupports ** aResult) -{ - *aResult = new nsISO2022JPToUnicode(); - return (*aResult == NULL)? NS_ERROR_OUT_OF_MEMORY : NS_OK; -} - -// XXX quick hack so I don't have to include nsICharsetConverterManager -extern "C" const nsID kCharsetConverterManagerCID; - -// XXX find a better place for this shift tables +// XXX renames static PRInt16 cs0201ShiftTable[] = { 2, u1ByteCharset , ShiftCell(u1ByteChar, 1, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x7F), @@ -59,12 +32,31 @@ static PRInt16 cs0201ShiftTable[] = { }; static PRInt16 cs0208ShiftTable[] = { - 0, u2BytesGRCharset, + 0, u2BytesCharset, ShiftCell(0,0,0,0,0,0,0,0) }; -// XXX verify validity of tables and charset specs -// XXX 0201 seems to be wrong for the ASCII- roman +//---------------------------------------------------------------------- +// Class nsISO2022JPToUnicode [implementation] + +nsISO2022JPToUnicode::nsISO2022JPToUnicode() +: nsBufferDecoderSupport() +{ + mHelper = nsnull; + + Reset(); +} + +nsISO2022JPToUnicode::~nsISO2022JPToUnicode() +{ + NS_IF_RELEASE(mHelper); +} + +nsresult nsISO2022JPToUnicode::CreateInstance(nsISupports ** aResult) +{ + *aResult = new nsISO2022JPToUnicode(); + return (*aResult == NULL)? NS_ERROR_OUT_OF_MEMORY : NS_OK; +} nsresult nsISO2022JPToUnicode::ConvertBuffer(const char ** aSrc, const char * aSrcEnd, @@ -80,11 +72,10 @@ nsresult nsISO2022JPToUnicode::ConvertBuffer(const char ** aSrc, nsresult res; if (mHelper == nsnull) { - // XXX change the helper object to have its own CID! - res = nsComponentManager::CreateInstance(kCharsetConverterManagerCID, NULL, - kIUnicodeDecodeUtilIID, (void**) & mHelper); + res = nsComponentManager::CreateInstance(kUnicodeDecodeHelperCID, NULL, + kIUnicodeDecodeHelperIID, (void**) & mHelper); - if (NS_FAILED(res)) return res; + if (NS_FAILED(res)) return NS_ERROR_UDEC_NOHELPER; } if (mCharset == kASCII) { @@ -105,7 +96,7 @@ nsresult nsISO2022JPToUnicode::ConvertBuffer(const char ** aSrc, res = NS_PARTIAL_MORE_OUTPUT; } else res = NS_OK; - res = mHelper->Convert(dest, 0, &destLen, src, 0, &srcLen, kOnError_Signal, + res = mHelper->ConvertByTable(src, &srcLen, dest, &destLen, (uShiftTable*) &cs0201ShiftTable, (uMappingTable*)&g_ut0201Mapping); *aSrc = src + srcLen; *aDest = dest + destLen; @@ -121,7 +112,7 @@ nsresult nsISO2022JPToUnicode::ConvertBuffer(const char ** aSrc, res = NS_PARTIAL_MORE_INPUT; } else res = NS_OK; - res = mHelper->Convert(dest, 0, &destLen, src, 0, &srcLen, kOnError_Signal, + res = mHelper->ConvertByTable(src, &srcLen, dest, &destLen, (uShiftTable*) &cs0208ShiftTable, (uMappingTable*)&g_ut0208Mapping); *aSrc = src + srcLen; *aDest = dest + destLen; @@ -134,18 +125,13 @@ nsresult nsISO2022JPToUnicode::ConvertBuffer(const char ** aSrc, } //---------------------------------------------------------------------- -// Interface nsICharsetConverter [implementation] +// Subclassing of nsBufferDecoderSupport class [implementation] -NS_IMETHODIMP nsISO2022JPToUnicode::Convert(PRUnichar * aDest, - PRInt32 aDestOffset, - PRInt32 * aDestLength, - const char * aSrc, - PRInt32 aSrcOffset, - PRInt32 * aSrcLength) +NS_IMETHODIMP nsISO2022JPToUnicode::ConvertNoBuff(const char * aSrc, + PRInt32 * aSrcLength, + PRUnichar * aDest, + PRInt32 * aDestLength) { - aSrc += aSrcOffset; - aDest += aDestOffset; - const char * srcEnd = aSrc + (*aSrcLength); const char * src = aSrc; PRUnichar * destEnd = aDest + (*aDestLength); @@ -158,31 +144,15 @@ NS_IMETHODIMP nsISO2022JPToUnicode::Convert(PRUnichar * aDest, case 0: if (*src == 27) { - if (mBuffLen > 0) res = NS_ERROR_ILLEGAL_INPUT; - else mState = 1; + mState = 1; } else if (dest >= destEnd) { res = NS_PARTIAL_MORE_OUTPUT; src--; // don't advance! } else { // here: src < srcEnd, dest < destEnd - if (mBuffLen > 0) { - // fill internal buffer - mBuffLen = 0; - mBuff[1] = *src++; - p = mBuff; - res = ConvertBuffer(&p, p+2, &dest, destEnd); - if (res != NS_OK) res = NS_ERROR_UNEXPECTED; - } else { - // find the end of this run - for (p=src; ((p < srcEnd) && (*p != 27)); p++) {;} - res = ConvertBuffer(&src, p, &dest, destEnd); - if (res == NS_PARTIAL_MORE_INPUT) if (p == srcEnd) { - mBuff[0] = *src++; - mBuffLen = 1; - } else { - res = NS_ERROR_ILLEGAL_INPUT; - } - } + // find the end of this run + for (p=src; ((p < srcEnd) && (*p != 27)); p++) {} + res = ConvertBuffer(&src, p, &dest, destEnd); src--; // we did our own advance here } break; @@ -242,36 +212,18 @@ NS_IMETHODIMP nsISO2022JPToUnicode::Convert(PRUnichar * aDest, return res; } -NS_IMETHODIMP nsISO2022JPToUnicode::Finish(PRUnichar * aDest, - PRInt32 aDestOffset, - PRInt32 * aDestLength) +NS_IMETHODIMP nsISO2022JPToUnicode::GetMaxLength(const char * aSrc, + PRInt32 aSrcLength, + PRInt32 * aDestLength) { - // not much to write - *aDestLength = 0; - return NS_OK; -} - -NS_IMETHODIMP nsISO2022JPToUnicode::Length(const char * aSrc, - PRInt32 aSrcOffset, - PRInt32 aSrcLength, - PRInt32 * aDestLength) -{ - // approximation for the worst case + // worst case *aDestLength = aSrcLength; return NS_OK; } NS_IMETHODIMP nsISO2022JPToUnicode::Reset() { - mBuffLen = 0; mState = 0; mCharset = kASCII; - - return NS_OK; -} - -NS_IMETHODIMP nsISO2022JPToUnicode::SetInputErrorBehavior(PRInt32 aBehavior) -{ - // we are supporting only the kOnError_Signal behavior in this implementation - return NS_OK; + return nsBufferDecoderSupport::Reset(); } diff --git a/intl/uconv/ucvja2/nsISO2022JPToUnicode.h b/intl/uconv/ucvja2/nsISO2022JPToUnicode.h index 3db098cdeab..ce153c028a7 100644 --- a/intl/uconv/ucvja2/nsISO2022JPToUnicode.h +++ b/intl/uconv/ucvja2/nsISO2022JPToUnicode.h @@ -20,13 +20,7 @@ #ifndef nsISO2022JPToUnicode_h___ #define nsISO2022JPToUnicode_h___ -#include "nsIUnicodeDecoder.h" -#include "nsIUnicodeDecodeUtil.h" - -//---------------------------------------------------------------------- -// Global functions and data [declaration] - -#define BUFFSIZE 2 // the size of the buffer for partial conversions +#include "nsUCvJa2Support.h" //---------------------------------------------------------------------- // Class nsISO2022JPToUnicode [declaration] @@ -51,10 +45,8 @@ * @created 09/Feb/1998 * @author Catalin Rotaru [CATA] */ -class nsISO2022JPToUnicode : public nsIUnicodeDecoder +class nsISO2022JPToUnicode : public nsBufferDecoderSupport { - NS_DECL_ISUPPORTS - public: /** @@ -70,22 +62,9 @@ public: /** * Static class constructor. */ - static nsresult CreateInstance(nsISupports **aResult); + static nsresult CreateInstance(nsISupports ** aResult); - //-------------------------------------------------------------------- - // Interface nsIUnicodeDecoder [declaration] - - NS_IMETHOD Convert(PRUnichar * aDest, PRInt32 aDestOffset, - PRInt32 * aDestLength,const char * aSrc, PRInt32 aSrcOffset, - PRInt32 * aSrcLength); - NS_IMETHOD Finish(PRUnichar * aDest, PRInt32 aDestOffset, - PRInt32 * aDestLength); - NS_IMETHOD Length(const char * aSrc, PRInt32 aSrcOffset, PRInt32 aSrcLength, - PRInt32 * aDestLength); - NS_IMETHOD Reset(); - NS_IMETHOD SetInputErrorBehavior(PRInt32 aBehavior); - -private: +protected: enum { kASCII, @@ -97,13 +76,19 @@ private: PRInt32 mState; // current state of the state machine PRInt32 mCharset; // current character set - char mBuff[BUFFSIZE]; // buffer for the partial conversions - PRInt32 mBuffLen; + nsIUnicodeDecodeHelper * mHelper; // decoder helper object - nsIUnicodeDecodeUtil * mHelper; // decoder helper object - - nsresult ConvertBuffer(const char ** aSrc, const char * aSrcEnd, + NS_IMETHOD ConvertBuffer(const char ** aSrc, const char * aSrcEnd, PRUnichar ** aDest, PRUnichar * aDestEnd); + + //-------------------------------------------------------------------- + // Subclassing of nsBufferDecoderSupport class [declaration] + + NS_IMETHOD ConvertNoBuff(const char * aSrc, PRInt32 * aSrcLength, + PRUnichar * aDest, PRInt32 * aDestLength); + NS_IMETHOD GetMaxLength(const char * aSrc, PRInt32 aSrcLength, + PRInt32 * aDestLength); + NS_IMETHOD Reset(); }; #endif /* nsISO2022JPToUnicode_h___ */ diff --git a/intl/uconv/ucvja2/nsUnicodeToISO2022JP.cpp b/intl/uconv/ucvja2/nsUnicodeToISO2022JP.cpp index 5035e85dae2..a130ca5e7ab 100644 --- a/intl/uconv/ucvja2/nsUnicodeToISO2022JP.cpp +++ b/intl/uconv/ucvja2/nsUnicodeToISO2022JP.cpp @@ -18,18 +18,59 @@ */ #include "nsUnicodeToISO2022JP.h" +#include "nsIComponentManager.h" +#include "nsUCVJA2Dll.h" //---------------------------------------------------------------------- // Global functions and data [declaration] +static PRUint16 g_ufAsciiMapping [] = { + 0x0001, 0x0004, 0x0005, 0x0008, 0x0000, 0x0000, 0x007F, 0x0000 +}; + +static PRInt16 g_ufAsciiShift [] = { + 0, u1ByteCharset, + ShiftCell(0,0,0,0,0,0,0,0) +}; + +static PRInt16 g_uf0201Shift [] = { + 2, u1ByteCharset , + ShiftCell(u1ByteChar, 1, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x7F), + ShiftCell(u1ByteChar, 1, 0xA1, 0xDF, 0x00, 0xA1, 0x00, 0xDF), +}; + +static PRInt16 g_uf0208Shift [] = { + 0, u2BytesCharset, + ShiftCell(0,0,0,0,0,0,0,0) +}; + +static PRUint16 * g_ufMappingTables[4] = { + g_ufAsciiMapping, + g_uf0201Mapping, + g_uf0208Mapping, + g_uf0208Mapping, +}; + +static PRInt16 * g_ufShiftTables[4] = { + g_ufAsciiShift, + g_uf0201Shift, + g_uf0208Shift, + g_uf0208Shift, +}; + //---------------------------------------------------------------------- // Class nsUnicodeToISO2022JP [implementation] nsUnicodeToISO2022JP::nsUnicodeToISO2022JP() -: nsTableEncoderSupport((uShiftTable*) NULL, - (uMappingTable*) NULL) +: nsEncoderSupport() { - // XXX write me + mHelper = NULL; + Reset(); +} + +nsUnicodeToISO2022JP::~nsUnicodeToISO2022JP() +{ + NS_IF_RELEASE(mHelper); } nsresult nsUnicodeToISO2022JP::CreateInstance(nsISupports ** aResult) @@ -38,14 +79,126 @@ nsresult nsUnicodeToISO2022JP::CreateInstance(nsISupports ** aResult) return (*aResult == NULL)? NS_ERROR_OUT_OF_MEMORY : NS_OK; } +nsresult nsUnicodeToISO2022JP::ChangeCharset(PRInt32 aCharset, + char * aDest, + PRInt32 * aDestLength) +{ + if (aCharset == mCharset) { + *aDestLength = 0; + return NS_OK; + } + + if (*aDestLength < 3) { + *aDestLength = 0; + return NS_OK_UENC_MOREOUTPUT; + } + + switch (aCharset) { + case 0: + aDest[0] = 0x1b; + aDest[1] = '('; + aDest[2] = 'B'; + break; + case 1: + aDest[0] = 0x1b; + aDest[1] = '('; + aDest[2] = 'J'; + break; + case 2: + aDest[0] = 0x1b; + aDest[1] = '$'; + aDest[2] = '@'; + break; + case 3: + aDest[0] = 0x1b; + aDest[1] = '$'; + aDest[2] = 'B'; + break; + } + + mCharset = aCharset; + *aDestLength = 3; + return NS_OK; +} + //---------------------------------------------------------------------- // Subclassing of nsTableEncoderSupport class [implementation] +NS_IMETHODIMP nsUnicodeToISO2022JP::ConvertNoBuffNoErr( + const PRUnichar * aSrc, + PRInt32 * aSrcLength, + char * aDest, + PRInt32 * aDestLength) +{ + nsresult res; + + if (mHelper == nsnull) { + res = nsComponentManager::CreateInstance(kUnicodeEncodeHelperCID, NULL, + kIUnicodeEncodeHelperIID, (void**) & mHelper); + + if (NS_FAILED(res)) return NS_ERROR_UENC_NOHELPER; + } + + const PRUnichar * src = aSrc; + const PRUnichar * srcEnd = aSrc + *aSrcLength; + char * dest = aDest; + char * destEnd = aDest + *aDestLength; + PRInt32 bcr, bcw; + PRInt32 i; + + while (src < srcEnd) { + for (i=0; i<4; i++) { + bcr = 1; + bcw = destEnd - dest; + res = mHelper->ConvertByTable(src, &bcr, dest, &bcw, + (uShiftTable *) g_ufShiftTables[i], + (uMappingTable *) g_ufMappingTables[i]); + if (res != NS_ERROR_UENC_NOMAPPING) break; + } + + if (i>=4) res = NS_ERROR_UENC_NOMAPPING; + if (res != NS_OK) break; + + bcw = destEnd - dest; + res = ChangeCharset(i, dest, &bcw); + dest += bcw; + if (res != NS_OK) break; + + bcr = srcEnd - src; + bcw = destEnd - dest; + res = mHelper->ConvertByTable(src, &bcr, dest, &bcw, + (uShiftTable *) g_ufShiftTables[i], + (uMappingTable *) g_ufMappingTables[i]); + src += bcr; + dest += bcw; + + if ((res != NS_OK) && (res != NS_ERROR_UENC_NOMAPPING)) break; + if (res == NS_ERROR_UENC_NOMAPPING) src--; + } + + *aSrcLength = src - aSrc; + *aDestLength = dest - aDest; + return res; +} + +NS_IMETHODIMP nsUnicodeToISO2022JP::FinishNoBuff(char * aDest, + PRInt32 * aDestLength) +{ + ChangeCharset(0, aDest, aDestLength); + return NS_OK; +} + NS_IMETHODIMP nsUnicodeToISO2022JP::GetMaxLength(const PRUnichar * aSrc, PRInt32 aSrcLength, PRInt32 * aDestLength) { - // XXX write me - *aDestLength = aSrcLength; - return NS_OK_UENC_EXACTLENGTH; + // worst case + *aDestLength = 5*aSrcLength; + return NS_OK; +} + +NS_IMETHODIMP nsUnicodeToISO2022JP::Reset() +{ + mCharset = 0; + return nsEncoderSupport::Reset(); } diff --git a/intl/uconv/ucvja2/nsUnicodeToISO2022JP.h b/intl/uconv/ucvja2/nsUnicodeToISO2022JP.h index ed784620da7..974a5aaa11d 100644 --- a/intl/uconv/ucvja2/nsUnicodeToISO2022JP.h +++ b/intl/uconv/ucvja2/nsUnicodeToISO2022JP.h @@ -31,7 +31,7 @@ * @created 17/Feb/1999 * @author Catalin Rotaru [CATA] */ -class nsUnicodeToISO2022JP : public nsTableEncoderSupport +class nsUnicodeToISO2022JP : public nsEncoderSupport { public: @@ -40,6 +40,11 @@ public: */ nsUnicodeToISO2022JP(); + /** + * Class destructor. + */ + virtual ~nsUnicodeToISO2022JP(); + /** * Static class constructor. */ @@ -47,11 +52,21 @@ public: protected: + PRInt32 mCharset; // current character set + nsIUnicodeEncodeHelper * mHelper; // encoder helper object + + nsresult ChangeCharset(PRInt32 aCharset, char * aDest, + PRInt32 * aDestLength); + //-------------------------------------------------------------------- // Subclassing of nsEncoderSupport class [declaration] + NS_IMETHOD ConvertNoBuffNoErr(const PRUnichar * aSrc, PRInt32 * aSrcLength, + char * aDest, PRInt32 * aDestLength); + NS_IMETHOD FinishNoBuff(char * aDest, PRInt32 * aDestLength); NS_IMETHOD GetMaxLength(const PRUnichar * aSrc, PRInt32 aSrcLength, PRInt32 * aDestLength); + NS_IMETHOD Reset(); }; #endif /* nsUnicodeToISO2022JP_h___ */