more work on UTF-7 converters

This commit is contained in:
cata%netscape.com 1999-06-07 18:49:12 +00:00
parent b6e1445779
commit 04a34ece10
12 changed files with 780 additions and 55 deletions

View File

@ -64,6 +64,7 @@ CPPSRCS = \
nsVISCIIToUnicode.cpp \
nsVPSToUnicode.cpp \
nsUTF8ToUnicode.cpp \
nsUTF7ToUnicode.cpp \
nsMUTF7ToUnicode.cpp \
nsUnicodeToISO88591.cpp \
nsUnicodeToISO88592.cpp \
@ -100,6 +101,7 @@ CPPSRCS = \
nsUnicodeToVISCII.cpp \
nsUnicodeToVPS.cpp \
nsUnicodeToUTF8.cpp \
nsUnicodeToUTF7.cpp \
nsUnicodeToMUTF7.cpp \
ns1ByteToUnicodeBase.cpp \
nsUCvLatinSupport.cpp \

View File

@ -62,6 +62,7 @@ CPPSRCS = \
nsVISCIIToUnicode.cpp \
nsVPSToUnicode.cpp \
nsUTF8ToUnicode.cpp \
nsUTF7ToUnicode.cpp \
nsMUTF7ToUnicode.cpp \
nsUnicodeToISO88591.cpp \
nsUnicodeToISO88592.cpp \
@ -94,6 +95,7 @@ CPPSRCS = \
nsUnicodeToMacUkrainian.cpp \
nsUnicodeToMacIcelandic.cpp \
nsUnicodeToUTF8.cpp \
nsUnicodeToUTF7.cpp \
nsUnicodeToMUTF7.cpp \
nsUnicodeToARMSCII8.cpp \
nsUnicodeToTCVN5712.cpp \
@ -131,6 +133,7 @@ CPP_OBJS= \
.\$(OBJDIR)\nsMacGreekToUnicode.obj \
.\$(OBJDIR)\nsMacTurkishToUnicode.obj \
.\$(OBJDIR)\nsUTF8ToUnicode.obj \
.\$(OBJDIR)\nsUTF7ToUnicode.obj \
.\$(OBJDIR)\nsMUTF7ToUnicode.obj \
.\$(OBJDIR)\nsMacCroatianToUnicode.obj \
.\$(OBJDIR)\nsMacRomanianToUnicode.obj \
@ -167,6 +170,7 @@ CPP_OBJS= \
.\$(OBJDIR)\nsUnicodeToMacGreek.obj \
.\$(OBJDIR)\nsUnicodeToMacTurkish.obj \
.\$(OBJDIR)\nsUnicodeToUTF8.obj \
.\$(OBJDIR)\nsUnicodeToUTF7.obj \
.\$(OBJDIR)\nsUnicodeToMUTF7.obj \
.\$(OBJDIR)\nsUnicodeToMacCroatian.obj \
.\$(OBJDIR)\nsUnicodeToMacRomanian.obj \

View File

@ -19,24 +19,11 @@
#include "nsMUTF7ToUnicode.h"
//----------------------------------------------------------------------
// Global functions and data [declaration]
static PRUint16 g_utMappingTable[] = {
#include "cp1252.ut"
};
static PRInt16 g_utShiftTable[] = {
0, u1ByteCharset ,
ShiftCell(0,0,0,0,0,0,0,0)
};
//----------------------------------------------------------------------
// Class nsMUTF7ToUnicode [implementation]
nsMUTF7ToUnicode::nsMUTF7ToUnicode()
: nsOneByteDecoderSupport((uShiftTable*) &g_utShiftTable,
(uMappingTable*) &g_utMappingTable)
: nsBasicUTF7Decoder(',', '&')
{
}

View File

@ -20,18 +20,18 @@
#ifndef nsMUTF7ToUnicode_h___
#define nsMUTF7ToUnicode_h___
#include "nsUCvLatinSupport.h"
#include "nsUTF7ToUnicode.h"
//----------------------------------------------------------------------
// Class nsMUTF7ToUnicode [declaration]
/**
* A character set converter from MUTF7 to Unicode.
* A character set converter from Modified UTF7 to Unicode.
*
* @created 18/May/1999
* @author Catalin Rotaru [CATA]
*/
class nsMUTF7ToUnicode : public nsOneByteDecoderSupport
class nsMUTF7ToUnicode : public nsBasicUTF7Decoder
{
public:

View File

@ -198,6 +198,11 @@ NS_DECLARE_ID(kVPSToUnicodeCID,
NS_DECLARE_ID(kUTF8ToUnicodeCID,
0x5534ddc0, 0xdd96, 0x11d2, 0x8a, 0xac, 0x0, 0x60, 0x8, 0x11, 0xa8, 0x36);
// Class ID for our UTF7ToUnicode charset converter
// {77CFAAF1-1CF4-11d3-8AAF-00600811A836}
NS_DECLARE_ID(kUTF7ToUnicodeCID,
0x77cfaaf1, 0x1cf4, 0x11d3, 0x8a, 0xaf, 0x0, 0x60, 0x8, 0x11, 0xa8, 0x36);
// Class ID for our MUTF7ToUnicode charset converter
// {B57F97C1-0D70-11d3-8AAE-00600811A836}
NS_DECLARE_ID(kMUTF7ToUnicodeCID,
@ -377,6 +382,11 @@ NS_DECLARE_ID(kUnicodeToVPSCID,
NS_DECLARE_ID(kUnicodeToUTF8CID,
0x7c657d18, 0xec5e, 0x11d2, 0x8a, 0xac, 0x0, 0x60, 0x8, 0x11, 0xa8, 0x36);
// Class ID for our UnicodeToUTF7 charset converter
// {77CFAAF2-1CF4-11d3-8AAF-00600811A836}
NS_DECLARE_ID(kUnicodeToUTF7CID,
0x77cfaaf2, 0x1cf4, 0x11d3, 0x8a, 0xaf, 0x0, 0x60, 0x8, 0x11, 0xa8, 0x36);
// Class ID for our UnicodeToMUTF7 charset converter
// {B57F97C2-0D70-11d3-8AAE-00600811A836}
NS_DECLARE_ID(kUnicodeToMUTF7CID,

View File

@ -62,6 +62,7 @@
#include "nsVISCIIToUnicode.h"
#include "nsVPSToUnicode.h"
#include "nsUTF8ToUnicode.h"
#include "nsUTF7ToUnicode.h"
#include "nsMUTF7ToUnicode.h"
#include "nsUnicodeToISO88591.h"
#include "nsUnicodeToISO88592.h"
@ -98,6 +99,7 @@
#include "nsUnicodeToVISCII.h"
#include "nsUnicodeToVPS.h"
#include "nsUnicodeToUTF8.h"
#include "nsUnicodeToUTF7.h"
#include "nsUnicodeToMUTF7.h"
// just for NS_IMPL_IDS; this is a good, central place to implement GUIDs
@ -340,10 +342,16 @@ FactoryData g_FactoryData[] =
"UTF-8",
"Unicode"
},
{
&kUTF7ToUnicodeCID,
nsUTF7ToUnicode::CreateInstance,
"UTF-7",
"Unicode"
},
{
&kMUTF7ToUnicodeCID,
nsMUTF7ToUnicode::CreateInstance,
"MUTF-7",
"x-imap4-modified-utf7",
"Unicode"
},
{
@ -556,11 +564,17 @@ FactoryData g_FactoryData[] =
"Unicode",
"UTF-8"
},
{
&kUnicodeToUTF7CID,
nsUnicodeToUTF7::CreateInstance,
"Unicode",
"UTF-7"
},
{
&kUnicodeToMUTF7CID,
nsUnicodeToMUTF7::CreateInstance,
"Unicode",
"MUTF-7"
"x-imap4-modified-utf7"
}
};

View File

@ -0,0 +1,259 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
#include "nsUTF7ToUnicode.h"
#define ENC_DIRECT 0
#define ENC_BASE64 1
//----------------------------------------------------------------------
// Class nsBasicUTF7Decoder [implementation]
nsBasicUTF7Decoder::nsBasicUTF7Decoder(char aLastChar, char aEscChar)
: nsBufferDecoderSupport()
{
mLastChar = aLastChar;
mEscChar = aEscChar;
Reset();
}
nsresult nsBasicUTF7Decoder::DecodeDirect(
const char * aSrc,
PRInt32 * aSrcLength,
PRUnichar * aDest,
PRInt32 * aDestLength)
{
const char * srcEnd = aSrc + *aSrcLength;
const char * src = aSrc;
PRUnichar * destEnd = aDest + *aDestLength;
PRUnichar * dest = aDest;
nsresult res = NS_OK;
char ch;
while (src < srcEnd) {
ch = *src;
// stop when we meet other chars or end of direct encoded seq.
if ((ch < 0x20) || (ch > 0x7e) || (ch == mEscChar)) {
res = NS_ERROR_UDEC_ILLEGALINPUT;
break;
}
if (dest >= destEnd) {
res = NS_OK_UDEC_MOREOUTPUT;
break;
} else {
*dest++ = ch;
src++;
}
}
*aSrcLength = src - aSrc;
*aDestLength = dest - aDest;
return res;
}
nsresult nsBasicUTF7Decoder::DecodeBase64(
const char * aSrc,
PRInt32 * aSrcLength,
PRUnichar * aDest,
PRInt32 * aDestLength)
{
const char * srcEnd = aSrc + *aSrcLength;
const char * src = aSrc;
PRUnichar * destEnd = aDest + *aDestLength;
PRUnichar * dest = aDest;
nsresult res = NS_OK;
char ch;
PRUint32 value;
while (src < srcEnd) {
ch = *src;
// stop when we meet other chars or end of direct encoded seq.
value = CharToValue(ch);
if (value == -1) {
res = NS_ERROR_UDEC_ILLEGALINPUT;
break;
}
switch (mEncStep) {
case 0:
mEncBits = value << 10;
break;
case 1:
mEncBits += value << 4;
break;
case 2:
if (dest >= destEnd) {
res = NS_OK_UDEC_MOREOUTPUT;
break;
}
mEncBits += value >> 2;
*(dest++) = (PRUnichar) mEncBits;
mEncBits = (value & 0x03) << 14;
break;
case 3:
mEncBits += value << 8;
break;
case 4:
mEncBits += value << 2;
break;
case 5:
if (dest >= destEnd) {
res = NS_OK_UDEC_MOREOUTPUT;
break;
}
mEncBits += value >> 4;
*(dest++) = (PRUnichar) mEncBits;
mEncBits = (value & 0x03) << 12;
break;
case 6:
mEncBits += value << 6;
break;
case 7:
if (dest >= destEnd) {
res = NS_OK_UDEC_MOREOUTPUT;
break;
}
mEncBits += value;
*(dest++) = (PRUnichar) mEncBits;
mEncBits = 0;
break;
}
if (res != NS_OK) break;
src++;
(++mEncStep)%=8;
}
*aSrcLength = src - aSrc;
*aDestLength = dest - aDest;
return res;
}
PRUint32 nsBasicUTF7Decoder::CharToValue(char aChar) {
if ((aChar>='A')&&(aChar<='Z'))
return (PRUint8)(aChar-'A');
else if ((aChar>='a')&&(aChar<='z'))
return (PRUint8)(26+aChar-'a');
else if ((aChar>='0')&&(aChar<='9'))
return (PRUint8)(26+26+aChar-'0');
else if (aChar=='+')
return (PRUint8)(26+26+10);
else if (aChar=='/')
return (PRUint8)(26+26+10+1);
else
return -1;
}
//----------------------------------------------------------------------
// Subclassing of nsBufferDecoderSupport class [implementation]
NS_IMETHODIMP nsBasicUTF7Decoder::ConvertNoBuff(const char * aSrc,
PRInt32 * aSrcLength,
PRUnichar * aDest,
PRInt32 * aDestLength)
{
const char * srcEnd = aSrc + *aSrcLength;
const char * src = aSrc;
PRUnichar * destEnd = aDest + *aDestLength;
PRUnichar * dest = aDest;
PRInt32 bcr,bcw;
nsresult res = NS_OK;
char ch;
while (src < srcEnd) {
ch = *src;
// fist, attept to decode in the current mode
bcr = srcEnd - src;
bcw = destEnd - dest;
if (mEncoding == ENC_DIRECT)
res = DecodeDirect(src, &bcr, dest, &bcw);
else if ((mFreshBase64) && (*src == '-')) {
*dest = mEscChar;
bcr = 0;
bcw = 1;
res = NS_ERROR_UDEC_ILLEGALINPUT;
} else {
mFreshBase64 = PR_FALSE;
res = DecodeBase64(src, &bcr, dest, &bcw);
}
src += bcr;
dest += bcw;
// if an illegal char was encountered, test if it is an escape seq.
if (res == NS_ERROR_UDEC_ILLEGALINPUT) {
if (mEncoding == ENC_DIRECT) {
if (*src == mEscChar) {
mEncoding = ENC_BASE64;
mFreshBase64 = PR_TRUE;
src++;
res = NS_OK;
} else break;
} else {
if (*src == '-') {
mEncoding = ENC_DIRECT;
src++;
res = NS_OK;
} else break;
}
} else if (res != NS_OK) break;
}
*aSrcLength = src - aSrc;
*aDestLength = dest - aDest;
return res;
}
NS_IMETHODIMP nsBasicUTF7Decoder::GetMaxLength(const char * aSrc,
PRInt32 aSrcLength,
PRInt32 * aDestLength)
{
// worst case
*aDestLength = aSrcLength;
return NS_OK;
}
NS_IMETHODIMP nsBasicUTF7Decoder::Reset()
{
mEncoding = ENC_DIRECT;
mEncBits = 0;
mEncStep = 0;
return nsBufferDecoderSupport::Reset();
}
//----------------------------------------------------------------------
// Class nsUTF7ToUnicode [implementation]
// XXX Ok, you know that this is too close to the M-UTF-8.
// You need to change it according to the spec.
nsUTF7ToUnicode::nsUTF7ToUnicode()
: nsBasicUTF7Decoder('/', '+')
{
}
nsresult nsUTF7ToUnicode::CreateInstance(nsISupports ** aResult)
{
*aResult = new nsUTF7ToUnicode();
return (*aResult == NULL)? NS_ERROR_OUT_OF_MEMORY : NS_OK;
}

View File

@ -0,0 +1,92 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
#ifndef nsUTF7ToUnicode_h___
#define nsUTF7ToUnicode_h___
#include "nsUCvLatinSupport.h"
//----------------------------------------------------------------------
// Class nsBasicUTF7Decoder [declaration]
/**
* Basic class for a character set converter from UTF-7 to Unicode.
*
* @created 03/Jun/1999
* @author Catalin Rotaru [CATA]
*/
class nsBasicUTF7Decoder : public nsBufferDecoderSupport
{
public:
/**
* Class constructor.
*/
nsBasicUTF7Decoder(char aLastChar, char aEscChar);
protected:
PRInt32 mEncoding; // current encoding
PRUint32 mEncBits;
PRInt32 mEncStep;
char mLastChar;
char mEscChar;
PRBool mFreshBase64;
nsresult DecodeDirect(const char * aSrc, PRInt32 * aSrcLength,
PRUnichar * aDest, PRInt32 * aDestLength);
nsresult DecodeBase64(const char * aSrc, PRInt32 * aSrcLength,
PRUnichar * aDest, PRInt32 * aDestLength);
PRUint32 CharToValue(char aChar);
//--------------------------------------------------------------------
// 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();
};
//----------------------------------------------------------------------
// Class nsUTF7ToUnicode [declaration]
/**
* A character set converter from Modified UTF7 to Unicode.
*
* @created 18/May/1999
* @author Catalin Rotaru [CATA]
*/
class nsUTF7ToUnicode : public nsBasicUTF7Decoder
{
public:
/**
* Class constructor.
*/
nsUTF7ToUnicode();
/**
* Static class constructor.
*/
static nsresult CreateInstance(nsISupports **aResult);
};
#endif /* nsUTF7ToUnicode_h___ */

View File

@ -19,24 +19,11 @@
#include "nsUnicodeToMUTF7.h"
//----------------------------------------------------------------------
// Global functions and data [declaration]
static PRUint16 g_ufMappingTable[] = {
#include "8859-1.uf"
};
static PRInt16 g_ufShiftTable[] = {
0, u1ByteCharset ,
ShiftCell(0,0,0,0,0,0,0,0)
};
//----------------------------------------------------------------------
// Class nsUnicodeToMUTF7 [implementation]
nsUnicodeToMUTF7::nsUnicodeToMUTF7()
: nsTableEncoderSupport((uShiftTable*) &g_ufShiftTable,
(uMappingTable*) &g_ufMappingTable)
: nsBasicUTF7Encoder(',', '&')
{
}
@ -45,14 +32,3 @@ nsresult nsUnicodeToMUTF7::CreateInstance(nsISupports ** aResult)
*aResult = new nsUnicodeToMUTF7();
return (*aResult == NULL)? NS_ERROR_OUT_OF_MEMORY : NS_OK;
}
//----------------------------------------------------------------------
// Subclassing of nsTableEncoderSupport class [implementation]
NS_IMETHODIMP nsUnicodeToMUTF7::GetMaxLength(const PRUnichar * aSrc,
PRInt32 aSrcLength,
PRInt32 * aDestLength)
{
*aDestLength = aSrcLength;
return NS_OK_UENC_EXACTLENGTH;
}

View File

@ -20,18 +20,18 @@
#ifndef nsUnicodeToMUTF7_h___
#define nsUnicodeToMUTF7_h___
#include "nsUCvLatinSupport.h"
#include "nsUnicodeToUTF7.h"
//----------------------------------------------------------------------
// Class nsUnicodeToMUTF7 [declaration]
/**
* A character set converter from Unicode to MUTF7.
* A character set converter from Unicode to Modified UTF-7.
*
* @created 18/May/1999
* @author Catalin Rotaru [CATA]
*/
class nsUnicodeToMUTF7 : public nsTableEncoderSupport
class nsUnicodeToMUTF7 : public nsBasicUTF7Encoder
{
public:
@ -44,14 +44,6 @@ public:
* Static class constructor.
*/
static nsresult CreateInstance(nsISupports **aResult);
protected:
//--------------------------------------------------------------------
// Subclassing of nsEncoderSupport class [declaration]
NS_IMETHOD GetMaxLength(const PRUnichar * aSrc, PRInt32 aSrcLength,
PRInt32 * aDestLength);
};
#endif /* nsUnicodeToMUTF7_h___ */

View File

@ -0,0 +1,295 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
#include "nsUnicodeToUTF7.h"
//----------------------------------------------------------------------
// Global functions and data [declaration]
#define ENC_DIRECT 0
#define ENC_BASE64 1
//----------------------------------------------------------------------
// Class nsBasicUTF7Encoder [implementation]
nsBasicUTF7Encoder::nsBasicUTF7Encoder(char aLastChar, char aEscChar)
: nsEncoderSupport()
{
mLastChar = aLastChar;
mEscChar = aEscChar;
Reset();
}
nsresult nsBasicUTF7Encoder::ShiftEncoding(PRInt32 aEncoding,
char * aDest,
PRInt32 * aDestLength)
{
if (aEncoding == mEncoding) {
*aDestLength = 0;
return NS_OK;
}
nsresult res = NS_OK;
char * dest = aDest;
char * destEnd = aDest + *aDestLength;
if (mEncStep != 0) {
if (dest >= destEnd) return NS_OK_UENC_MOREOUTPUT;
*(dest++)=ValueToChar(mEncBits);
}
if (dest >= destEnd) {
res = NS_OK_UENC_MOREOUTPUT;
} else {
switch (aEncoding) {
case 0:
*(dest++) = '-';
break;
case 1:
*(dest++) = mEscChar;
break;
}
mEncoding = aEncoding;
}
*aDestLength = dest - aDest;
return res;
}
nsresult nsBasicUTF7Encoder::EncodeDirect(
const PRUnichar * aSrc,
PRInt32 * aSrcLength,
char * aDest,
PRInt32 * aDestLength)
{
nsresult res = NS_OK;
const PRUnichar * src = aSrc;
const PRUnichar * srcEnd = aSrc + *aSrcLength;
char * dest = aDest;
char * destEnd = aDest + *aDestLength;
PRUnichar ch;
while (src < srcEnd) {
ch = *src;
// stop when we reach Unicode chars
if ((ch < 0x20) || (ch > 0x7e)) break;
if (ch == mEscChar) {
// special case for the escape char
if (destEnd - dest < 1) {
res = NS_OK_UENC_MOREOUTPUT;
break;
} else {
*dest++ = (char)ch;
*dest++ = (char)'-';
src++;
}
} else {
//classic direct encoding
if (dest >= destEnd) {
res = NS_OK_UENC_MOREOUTPUT;
break;
} else {
*dest++ = (char)ch;
src++;
}
}
}
*aSrcLength = src - aSrc;
*aDestLength = dest - aDest;
return res;
}
nsresult nsBasicUTF7Encoder::EncodeBase64(
const PRUnichar * aSrc,
PRInt32 * aSrcLength,
char * aDest,
PRInt32 * aDestLength)
{
nsresult res = NS_OK;
const PRUnichar * src = aSrc;
const PRUnichar * srcEnd = aSrc + *aSrcLength;
char * dest = aDest;
char * destEnd = aDest + *aDestLength;
PRUnichar ch;
PRUint32 value;
while (src < srcEnd) {
ch = *src;
// stop when we reach printable US-ASCII chars
if ((ch >= 0x20) && (ch <= 0x7e)) break;
switch (mEncStep) {
case 0:
if (destEnd - dest < 2) {
res = NS_OK_UENC_MOREOUTPUT;
break;
}
value=ch>>10;
*(dest++)=ValueToChar(value);
value=(ch>>4)&0x3f;
*(dest++)=ValueToChar(value);
mEncBits=(ch&0x0f)<<2;
break;
case 1:
if (destEnd - dest < 3) {
res = NS_OK_UENC_MOREOUTPUT;
break;
}
value=mEncBits+(ch>>14);
*(dest++)=ValueToChar(value);
value=(ch>>8)&0x3f;
*(dest++)=ValueToChar(value);
value=(ch>>2)&0x3f;
*(dest++)=ValueToChar(value);
mEncBits=(ch&0x03)<<4;
break;
case 2:
if (destEnd - dest < 3) {
res = NS_OK_UENC_MOREOUTPUT;
break;
}
value=mEncBits+(ch>>12);
*(dest++)=ValueToChar(value);
value=(ch>>6)&0x3f;
*(dest++)=ValueToChar(value);
value=ch&0x3f;
*(dest++)=ValueToChar(value);
mEncBits=0;
break;
}
if (res != NS_OK) break;
src++;
(++mEncStep)%=3;
}
*aSrcLength = src - aSrc;
*aDestLength = dest - aDest;
return res;
}
char nsBasicUTF7Encoder::ValueToChar(PRUint32 aValue) {
if (aValue < 26)
return (char)('A'+aValue);
else if (aValue < 26 + 26)
return (char)('a' + aValue - 26);
else if (aValue < 26 + 26 + 10)
return (char)('0' + aValue - 26 - 26);
else if (aValue == 26 + 26 + 10)
return '+';
else if (aValue == 26 + 26 + 10 + 1)
return mLastChar;
else
return -1;
}
//----------------------------------------------------------------------
// Subclassing of nsEncoderSupport class [implementation]
NS_IMETHODIMP nsBasicUTF7Encoder::ConvertNoBuffNoErr(
const PRUnichar * aSrc,
PRInt32 * aSrcLength,
char * aDest,
PRInt32 * aDestLength)
{
nsresult res = NS_OK;
const PRUnichar * src = aSrc;
const PRUnichar * srcEnd = aSrc + *aSrcLength;
char * dest = aDest;
char * destEnd = aDest + *aDestLength;
PRInt32 bcr,bcw;
PRUnichar ch;
PRInt32 enc;
while (src < srcEnd) {
// find the encoding for the next char
ch = *src;
if ((ch >= 0x20) && (ch <= 0x7e))
enc = ENC_DIRECT;
else
enc = ENC_BASE64;
// if necessary, shift into the required encoding
bcw = destEnd - dest;
res = ShiftEncoding(enc, dest, &bcw);
dest += bcw;
if (res != NS_OK) break;
// now encode (as much as you can)
bcr = srcEnd - src;
bcw = destEnd - dest;
if (enc == ENC_DIRECT)
res = EncodeDirect(src, &bcr, dest, &bcw);
else
res = EncodeBase64(src, &bcr, dest, &bcw);
src += bcr;
dest += bcw;
if (res != NS_OK) break;
}
*aSrcLength = src - aSrc;
*aDestLength = dest - aDest;
return res;
}
NS_IMETHODIMP nsBasicUTF7Encoder::FinishNoBuff(char * aDest,
PRInt32 * aDestLength)
{
return ShiftEncoding(ENC_DIRECT, aDest, aDestLength);
}
NS_IMETHODIMP nsBasicUTF7Encoder::GetMaxLength(const PRUnichar * aSrc,
PRInt32 aSrcLength,
PRInt32 * aDestLength)
{
// worst case
*aDestLength = 5*aSrcLength;
return NS_OK;
}
NS_IMETHODIMP nsBasicUTF7Encoder::Reset()
{
mEncoding = ENC_DIRECT;
mEncBits = 0;
mEncStep = 0;
return nsEncoderSupport::Reset();
}
//----------------------------------------------------------------------
// Class nsUnicodeToUTF7 [implementation]
// XXX Ok, you know that this is too close to the M-UTF-8.
// You need to change it according to the spec.
nsUnicodeToUTF7::nsUnicodeToUTF7()
: nsBasicUTF7Encoder('/', '+')
{
}
nsresult nsUnicodeToUTF7::CreateInstance(nsISupports ** aResult)
{
*aResult = new nsUnicodeToUTF7();
return (*aResult == NULL)? NS_ERROR_OUT_OF_MEMORY : NS_OK;
}

View File

@ -0,0 +1,94 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
#ifndef nsUnicodeToUTF7_h___
#define nsUnicodeToUTF7_h___
#include "nsUCvLatinSupport.h"
//----------------------------------------------------------------------
// Class nsBasicUTF7Encoder [declaration]
/**
* Basic class for a character set converter from Unicode to UTF-7.
*
* @created 03/Jun/1999
* @author Catalin Rotaru [CATA]
*/
class nsBasicUTF7Encoder : public nsEncoderSupport
{
public:
/**
* Class constructor.
*/
nsBasicUTF7Encoder(char aLastChar, char aEscChar);
protected:
PRInt32 mEncoding; // current encoding
PRUint32 mEncBits;
PRInt32 mEncStep;
char mLastChar;
char mEscChar;
nsresult ShiftEncoding(PRInt32 aEncoding, char * aDest,
PRInt32 * aDestLength);
nsresult EncodeDirect(const PRUnichar * aSrc, PRInt32 * aSrcLength,
char * aDest, PRInt32 * aDestLength);
nsresult EncodeBase64(const PRUnichar * aSrc, PRInt32 * aSrcLength,
char * aDest, PRInt32 * aDestLength);
char ValueToChar(PRUint32 aValue);
//--------------------------------------------------------------------
// 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();
};
//----------------------------------------------------------------------
// Class nsUnicodeToUTF7 [declaration]
/**
* A character set converter from Unicode to UTF-7.
*
* @created 03/Jun/1999
* @author Catalin Rotaru [CATA]
*/
class nsUnicodeToUTF7 : public nsBasicUTF7Encoder
{
public:
/**
* Class constructor.
*/
nsUnicodeToUTF7();
/**
* Static class constructor.
*/
static nsresult CreateInstance(nsISupports **aResult);
};
#endif /* nsUnicodeToUTF7_h___ */