Back to index

lightning-sunbird  0.9+nobinonly
Public Types | Public Member Functions | Protected Member Functions | Protected Attributes
nsBasicUTF7Encoder Class Reference

Basic class for a character set converter from Unicode to UTF-7. More...

#include <nsUnicodeToUTF7.h>

Inheritance diagram for nsBasicUTF7Encoder:
Inheritance graph
[legend]
Collaboration diagram for nsBasicUTF7Encoder:
Collaboration graph
[legend]

List of all members.

Public Types

enum  { kOnError_Signal, kOnError_CallBack, kOnError_Replace }

Public Member Functions

 nsBasicUTF7Encoder (char aLastChar, char aEscChar)
 Class constructor.
NS_IMETHOD FillInfo (PRUint32 *aInfo)
NS_IMETHOD Convert (const PRUnichar *aSrc, PRInt32 *aSrcLength, char *aDest, PRInt32 *aDestLength)
 Converts the data from Unicode to a Charset.
NS_IMETHOD Finish (char *aDest, PRInt32 *aDestLength)
 Finishes the conversion.
NS_IMETHOD SetOutputErrorBehavior (PRInt32 aBehavior, nsIUnicharEncoder *aEncoder, PRUnichar aChar)
 Specify what to do when a character cannot be mapped into the dest charset.
NS_IMETHOD GetMaxLength (const PRUnichar *aSrc, PRInt32 aSrcLength, PRInt32 *aDestLength)
 Returns a quick estimation of the size of the buffer needed to hold the converted data.

Protected Member Functions

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)
virtual PRBool DirectEncodable (PRUnichar aChar)
NS_IMETHOD ConvertNoBuffNoErr (const PRUnichar *aSrc, PRInt32 *aSrcLength, char *aDest, PRInt32 *aDestLength)
 Convert method but without the buffer management stuff and without error handling stuff.
NS_IMETHOD FinishNoBuff (char *aDest, PRInt32 *aDestLength)
 Finish method but without the buffer management stuff.
NS_IMETHOD Reset ()
 Resets the charset converter so it may be recycled for a completely different and urelated buffer of data.
NS_IMETHOD ConvertNoBuff (const PRUnichar *aSrc, PRInt32 *aSrcLength, char *aDest, PRInt32 *aDestLength)
 Convert method but without the buffer management stuff and with error handling stuff.
nsresult FlushBuffer (char **aDest, const char *aDestEnd)
 Copy as much as possible from the internal buffer to the destination.

Protected Attributes

PRInt32 mEncoding
PRUint32 mEncBits
PRInt32 mEncStep
char mLastChar
char mEscChar
char * mBuffer
 Internal buffer for partial conversions.
PRInt32 mBufferCapacity
char * mBufferStart
char * mBufferEnd
PRInt32 mErrBehavior
 Error handling stuff.
nsCOMPtr< nsIUnicharEncodermErrEncoder
PRUnichar mErrChar
PRUint32 mMaxLengthFactor

Detailed Description

Basic class for a character set converter from Unicode to UTF-7.

03/Jun/1999

Author:
Catalin Rotaru [CATA]

Definition at line 52 of file nsUnicodeToUTF7.h.


Member Enumeration Documentation

anonymous enum [inherited]
Enumerator:
kOnError_Signal 
kOnError_CallBack 
kOnError_Replace 

Definition at line 136 of file nsIUnicodeEncoder.h.

       {
    kOnError_Signal,        // on an error, stop and signal
    kOnError_CallBack,      // on an error, call the error handler
    kOnError_Replace       // on an error, replace with a different character
  };

Constructor & Destructor Documentation

nsBasicUTF7Encoder::nsBasicUTF7Encoder ( char  aLastChar,
char  aEscChar 
)

Class constructor.

Definition at line 50 of file nsUnicodeToUTF7.cpp.

: nsEncoderSupport(5)
{
  mLastChar = aLastChar;
  mEscChar = aEscChar;
  Reset();
}

Here is the call graph for this function:


Member Function Documentation

NS_IMETHODIMP nsEncoderSupport::Convert ( const PRUnichar aSrc,
PRInt32 aSrcLength,
char *  aDest,
PRInt32 aDestLength 
) [virtual, inherited]

Converts the data from Unicode to a Charset.

About the byte ordering:

  • The input stream is Unicode, having the byte order which is internal for the machine on which the converter is running on.
  • For output, if the converter cares (that depends of the charset, for example a singlebyte will ignore the byte ordering) it should assume network order. If necessary and requested, we can add a method SetOutputByteOrder() so that the reverse order can be used, too. That method would have as default the assumed network order.

Unless there is not enough output space, this method must consume all the available input data! We don't have partial input for the Unicode charset. And for the last converted char, even if there is not enought output space, a partial ouput must be done until all available space will be used. The rest of the output should be buffered until more space becomes available. But this is not also true about the error handling method!!! So be very, very careful...

Parameters:
aSrc[IN] the source data buffer
aSrcLength[IN/OUT] the length of source data buffer; after conversion will contain the number of Unicode characters read
aDest[OUT] the destination data buffer
aDestLength[IN/OUT] the length of the destination data buffer; after conversion will contain the number of bytes written
Returns:
NS_OK_UENC_MOREOUTPUT if only a partial conversion was done; more output space is needed to continue NS_ERROR_UENC_NOMAPPING if character without mapping was encountered and the behavior was set to "signal".

Implements nsIUnicodeEncoder.

Definition at line 475 of file nsUCSupport.cpp.

{
  // we do all operations using pointers internally
  const PRUnichar * src = aSrc;
  const PRUnichar * srcEnd = aSrc + *aSrcLength;
  char * dest = aDest;
  char * destEnd = aDest + *aDestLength;

  PRInt32 bcr, bcw; // byte counts for read & write;
  nsresult res;

  res = FlushBuffer(&dest, destEnd);
  if (res == NS_OK_UENC_MOREOUTPUT) goto final;

  bcr = srcEnd - src;
  bcw = destEnd - dest;
  res = ConvertNoBuff(src, &bcr, dest, &bcw);
  src += bcr;
  dest += bcw;
  if ((res == NS_OK_UENC_MOREOUTPUT) && (dest < destEnd)) {
    // convert exactly one character into the internal buffer
    // at this point, there should be at least a char in the input
    for (;;) {
      bcr = 1;
      bcw = mBufferCapacity;
      res = ConvertNoBuff(src, &bcr, mBuffer, &bcw);

      if (res == NS_OK_UENC_MOREOUTPUT) {
        delete [] mBuffer;
        mBufferCapacity *= 2;
        mBuffer = new char [mBufferCapacity];
      } else {
        src += bcr;
        mBufferStart = mBufferEnd = mBuffer;
        mBufferEnd += bcw;
        break;
      }
    }

    res = FlushBuffer(&dest, destEnd);
  }

final:
  *aSrcLength   -= srcEnd - src;
  *aDestLength  -= destEnd - dest;
  return res;
}

Here is the call graph for this function:

NS_IMETHODIMP nsEncoderSupport::ConvertNoBuff ( const PRUnichar aSrc,
PRInt32 aSrcLength,
char *  aDest,
PRInt32 aDestLength 
) [protected, inherited]

Convert method but without the buffer management stuff and with error handling stuff.

Reimplemented in nsUnicodeToGBK, nsUnicodeToHZ, nsUnicodeToGB2312GL, and nsUnicodeToGB2312V2.

Definition at line 394 of file nsUCSupport.cpp.

{
  // we do all operations using pointers internally
  const PRUnichar * src = aSrc;
  const PRUnichar * srcEnd = aSrc + *aSrcLength;
  char * dest = aDest;
  char * destEnd = aDest + *aDestLength;

  PRInt32 bcr, bcw; // byte counts for read & write;
  nsresult res;

  for (;;) {
    bcr = srcEnd - src;
    bcw = destEnd - dest;
    res = ConvertNoBuffNoErr(src, &bcr, dest, &bcw);
    src += bcr;
    dest += bcw;

    if (res == NS_ERROR_UENC_NOMAPPING) {
      if (mErrBehavior == kOnError_Replace) {
        const PRUnichar buff[] = {mErrChar};
        bcr = 1;
        bcw = destEnd - dest;
        src--; // back the input: maybe the guy won't consume consume anything.
        res = ConvertNoBuffNoErr(buff, &bcr, dest, &bcw);
        src += bcr;
        dest += bcw;
        if (res != NS_OK) break;
      } else if (mErrBehavior == kOnError_CallBack) {
        bcw = destEnd - dest;
        src--;
        res = mErrEncoder->Convert(*src, dest, &bcw);
        dest += bcw;
        // if enought output space then the last char was used
        if (res != NS_OK_UENC_MOREOUTPUT) src++;
        if (res != NS_OK) break;
      } else break;
    }
    else break;
  }

  *aSrcLength   -= srcEnd - src;
  *aDestLength  -= destEnd - dest;
  return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

NS_IMETHODIMP nsBasicUTF7Encoder::ConvertNoBuffNoErr ( const PRUnichar aSrc,
PRInt32 aSrcLength,
char *  aDest,
PRInt32 aDestLength 
) [protected, virtual]

Convert method but without the buffer management stuff and without error handling stuff.

Implements nsEncoderSupport.

Definition at line 245 of file nsUnicodeToUTF7.cpp.

{
  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 (DirectEncodable(ch)) 
      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;
}

Here is the call graph for this function:

PRBool nsBasicUTF7Encoder::DirectEncodable ( PRUnichar  aChar) [protected, virtual]

Reimplemented in nsUnicodeToUTF7.

Definition at line 236 of file nsUnicodeToUTF7.cpp.

                                                          {
  // spec says: printable US-ASCII chars
  if ((aChar >= 0x20) && (aChar <= 0x7e)) return PR_TRUE;
  else return PR_FALSE;
}

Here is the caller graph for this function:

nsresult nsBasicUTF7Encoder::EncodeBase64 ( const PRUnichar aSrc,
PRInt32 aSrcLength,
char *  aDest,
PRInt32 aDestLength 
) [protected]

Definition at line 150 of file nsUnicodeToUTF7.cpp.

{
  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 (DirectEncodable(ch)) 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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsBasicUTF7Encoder::EncodeDirect ( const PRUnichar aSrc,
PRInt32 aSrcLength,
char *  aDest,
PRInt32 aDestLength 
) [protected]

Definition at line 104 of file nsUnicodeToUTF7.cpp.

{
  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 (!DirectEncodable(ch)) 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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Implements nsEncoderSupport.

Definition at line 58 of file nsUnicodeToUTF7.cpp.

{
  memset(aInfo, 0xFF, (0x10000L >> 3));
  return NS_OK;
}

Here is the call graph for this function:

NS_IMETHODIMP nsEncoderSupport::Finish ( char *  aDest,
PRInt32 aDestLength 
) [virtual, inherited]

Finishes the conversion.

The converter has the possibility to write some extra data and flush its final state.

Parameters:
aDest[OUT] the destination data buffer
aDestLength[IN/OUT] the length of destination data buffer; after conversion it will contain the number of bytes written
Returns:
NS_OK_UENC_MOREOUTPUT if only a partial conversion was done; more output space is needed to continue

Implements nsIUnicodeEncoder.

Definition at line 526 of file nsUCSupport.cpp.

{
  // we do all operations using pointers internally
  char * dest = aDest;
  char * destEnd = aDest + *aDestLength;

  PRInt32 bcw; // byte count for write;
  nsresult res;

  res = FlushBuffer(&dest, destEnd);
  if (res == NS_OK_UENC_MOREOUTPUT) goto final;

  // do the finish into the internal buffer.
  for (;;) {
    bcw = mBufferCapacity;
    res = FinishNoBuff(mBuffer, &bcw);

    if (res == NS_OK_UENC_MOREOUTPUT) {
      delete [] mBuffer;
      mBufferCapacity *= 2;
      mBuffer = new char [mBufferCapacity];
    } else {
      mBufferStart = mBufferEnd = mBuffer;
      mBufferEnd += bcw;
      break;
    }
  }

  res = FlushBuffer(&dest, destEnd);

final:
  *aDestLength  -= destEnd - dest;
  return res;
}

Here is the call graph for this function:

NS_IMETHODIMP nsBasicUTF7Encoder::FinishNoBuff ( char *  aDest,
PRInt32 aDestLength 
) [protected]

Finish method but without the buffer management stuff.

Reimplemented from nsEncoderSupport.

Definition at line 292 of file nsUnicodeToUTF7.cpp.

{
  return ShiftEncoding(ENC_DIRECT, aDest, aDestLength);
}

Here is the call graph for this function:

nsresult nsEncoderSupport::FlushBuffer ( char **  aDest,
const char *  aDestEnd 
) [protected, inherited]

Copy as much as possible from the internal buffer to the destination.

Definition at line 450 of file nsUCSupport.cpp.

{
  PRInt32 bcr, bcw; // byte counts for read & write;
  nsresult res = NS_OK;
  char * dest = *aDest;

  if (mBufferStart < mBufferEnd) {
    bcr = mBufferEnd - mBufferStart;
    bcw = aDestEnd - dest;
    if (bcw < bcr) bcr = bcw;
    memcpy(dest, mBufferStart, bcr);
    dest += bcr;
    mBufferStart += bcr;

    if (mBufferStart < mBufferEnd) res = NS_OK_UENC_MOREOUTPUT;
  }

  *aDest = dest;
  return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

NS_IMETHODIMP nsEncoderSupport::GetMaxLength ( const PRUnichar aSrc,
PRInt32  aSrcLength,
PRInt32 aDestLength 
) [virtual, inherited]

Returns a quick estimation of the size of the buffer needed to hold the converted data.

Remember: this estimation is >= with the actual size of the buffer needed. It will be computed for the "worst case"

Parameters:
aSrc[IN] the source data buffer
aSrcLength[IN] the length of source data buffer
aDestLength[OUT] the needed size of the destination buffer
Returns:
NS_OK_UENC_EXACTLENGTH if an exact length was computed NS_OK if all we have is an approximation

Implements nsIUnicodeEncoder.

Definition at line 582 of file nsUCSupport.cpp.

{
  *aDestLength = aSrcLength * mMaxLengthFactor;
  return NS_OK;
}
NS_IMETHODIMP nsBasicUTF7Encoder::Reset ( ) [protected, virtual]

Resets the charset converter so it may be recycled for a completely different and urelated buffer of data.

Reimplemented from nsEncoderSupport.

Definition at line 298 of file nsUnicodeToUTF7.cpp.

Here is the caller graph for this function:

NS_IMETHODIMP nsEncoderSupport::SetOutputErrorBehavior ( PRInt32  aBehavior,
nsIUnicharEncoder aEncoder,
PRUnichar  aChar 
) [virtual, inherited]

Specify what to do when a character cannot be mapped into the dest charset.

Parameters:
aOrder[IN] the behavior; taken from the enum

Implements nsIUnicodeEncoder.

Definition at line 567 of file nsUCSupport.cpp.

{
  if (aBehavior == kOnError_CallBack && aEncoder == nsnull) 
    return NS_ERROR_NULL_POINTER;

  mErrEncoder = aEncoder;
  mErrBehavior = aBehavior;
  mErrChar = aChar;
  return NS_OK;
}
nsresult nsBasicUTF7Encoder::ShiftEncoding ( PRInt32  aEncoding,
char *  aDest,
PRInt32 aDestLength 
) [protected]

Definition at line 64 of file nsUnicodeToUTF7.cpp.

{
  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);
    mEncStep = 0;
    mEncBits = 0;
  }

  if (dest >= destEnd) {
    res = NS_OK_UENC_MOREOUTPUT;
  } else {
    switch (aEncoding) {
      case 0:
        *(dest++) = '-';
        mEncStep = 0;
        mEncBits = 0;
        break;
      case 1:
        *(dest++) = mEscChar;
        break;
    }
    mEncoding = aEncoding;
  }

  *aDestLength  = dest - aDest;
  return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char nsBasicUTF7Encoder::ValueToChar ( PRUint32  aValue) [protected]

Definition at line 221 of file nsUnicodeToUTF7.cpp.

                                                    { 
  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;
}

Here is the caller graph for this function:


Member Data Documentation

char* nsEncoderSupport::mBuffer [protected, inherited]

Internal buffer for partial conversions.

Definition at line 332 of file nsUCSupport.h.

Definition at line 333 of file nsUCSupport.h.

char* nsEncoderSupport::mBufferEnd [protected, inherited]

Definition at line 335 of file nsUCSupport.h.

char* nsEncoderSupport::mBufferStart [protected, inherited]

Definition at line 334 of file nsUCSupport.h.

Definition at line 66 of file nsUnicodeToUTF7.h.

Definition at line 65 of file nsUnicodeToUTF7.h.

Definition at line 67 of file nsUnicodeToUTF7.h.

PRInt32 nsEncoderSupport::mErrBehavior [protected, inherited]

Error handling stuff.

Definition at line 340 of file nsUCSupport.h.

PRUnichar nsEncoderSupport::mErrChar [protected, inherited]

Definition at line 342 of file nsUCSupport.h.

Definition at line 341 of file nsUCSupport.h.

char nsBasicUTF7Encoder::mEscChar [protected]

Definition at line 69 of file nsUnicodeToUTF7.h.

Definition at line 68 of file nsUnicodeToUTF7.h.

Definition at line 343 of file nsUCSupport.h.


The documentation for this class was generated from the following files: