Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions
nsUTF32ToUnicode.cpp File Reference
#include "nsUCSupport.h"
#include "nsUTF32ToUnicode.h"
#include <string.h>

Go to the source code of this file.

Defines

#define LE_STRING_TO_UCS4(s)   (*(PRUint32*) (s))
#define BE_STRING_TO_UCS4(s)

Functions

static nsresult ConvertCommon (const char *aSrc, PRInt32 *aSrcLength, PRUnichar *aDest, PRInt32 *aDestLength, PRUint16 *aState, PRUint8 *aBuffer, PRBool aIsLE)

Define Documentation

Value:
(PRUint8(*((s) + 3)) | (PRUint8(*((s) + 2)) << 8) |         \
         (PRUint8(*((s) + 1)) << 16) | (PRUint8(*(s)) << 24))

Definition at line 59 of file nsUTF32ToUnicode.cpp.

#define LE_STRING_TO_UCS4 (   s)    (*(PRUint32*) (s))

Definition at line 53 of file nsUTF32ToUnicode.cpp.


Function Documentation

static nsresult ConvertCommon ( const char *  aSrc,
PRInt32 aSrcLength,
PRUnichar aDest,
PRInt32 aDestLength,
PRUint16 aState,
PRUint8 aBuffer,
PRBool  aIsLE 
) [static]

Definition at line 64 of file nsUTF32ToUnicode.cpp.

{
   
  NS_ENSURE_TRUE(*aState < 4, NS_ERROR_INVALID_ARG);
  NS_ENSURE_TRUE(*aDestLength > 0, NS_ERROR_INVALID_ARG);

  const char *src = aSrc;
  const char *srcEnd = aSrc + *aSrcLength;
   
  PRUnichar *dest = aDest;
  PRUnichar *destEnd = aDest + *aDestLength;

  if (*aState > *aSrcLength) 
  {
    memcpy(aBuffer + 4 - *aState, src, *aSrcLength);
    *aDestLength = 0;
    *aState -= *aSrcLength;
    return NS_OK_UDEC_MOREINPUT;
  }

  PRUint32 ucs4;

  // prev. run left a partial UTF-32 seq. 
  if (*aState > 0)
  {
    memcpy(aBuffer + 4 - *aState, src, *aState);
    ucs4 =  aIsLE ? LE_STRING_TO_UCS4(aBuffer) : BE_STRING_TO_UCS4(aBuffer); 
    if (ucs4 < 0x10000L)  // BMP
    {
      // XXX Do we have to convert surrogate code points to the replacement
      // character (0xfffd)?  
      *dest++= PRUnichar(ucs4);
    }
    else if (ucs4 < 0x110000L)  // plane 1 through plane 16 
    {
      if (destEnd - dest < 2) 
      {
        *aSrcLength = 0;
        *aDestLength = 0;
        return NS_OK_UDEC_MOREOUTPUT;
      }
      // ((ucs4 - 0x10000) >> 10) + 0xd800;
      *dest++= PRUnichar((ucs4 >> 10) + 0xd7c0);  // high surrogate
      *dest++= PRUnichar(ucs4 & 0x3ffL | 0xdc00); // low surrogate
    }       
    // Codepoints in plane 17 and higher (> 0x10ffff)
    // are not representable in UTF-16 we use for the internal
    // character representation. This is not a problem
    // because Unicode/ISO 10646 will never assign characters
    // in plane 17 and higher. Therefore, we convert them
    // to Unicode replacement character (0xfffd).
    else                   
      *dest++ = 0xfffd;
    src += *aState;
    *aState = 0;
  }

  nsresult rv = NS_OK;  // conversion result

  for ( ; src < srcEnd && dest < destEnd; src += 4)
  {
    if (srcEnd - src < 4) 
    {
      // fill up aBuffer until src buffer gets exhausted.
      memcpy(aBuffer, src, srcEnd - src);
      *aState = 4 - (srcEnd - src); // set add. char to read in next run
      src = srcEnd;
      rv = NS_OK_UDEC_MOREINPUT;
      break;
    }

    ucs4 =  aIsLE ? LE_STRING_TO_UCS4(src) : BE_STRING_TO_UCS4(src); 
    if (ucs4 < 0x10000L)  // BMP
    {
      // XXX Do we have to convert surrogate code points to the replacement
      // character (0xfffd)?  
      *dest++= PRUnichar(ucs4);
    }
    else if (ucs4 < 0x110000L)  // plane 1 through plane 16 
    {
      if (destEnd - dest < 2) 
        break;
      // ((ucs4 - 0x10000) >> 10) + 0xd800;
      *dest++= PRUnichar((ucs4 >> 10) + 0xd7c0); 
      *dest++= PRUnichar(ucs4 & 0x3ffL | 0xdc00);
    }       
    else                       // plane 17 and higher
      *dest++ = 0xfffd;
  }

  //output not finished, output buffer too short
  if((NS_OK == rv) && (src < srcEnd) && (dest >= destEnd)) 
    rv = NS_OK_UDEC_MOREOUTPUT;

  *aSrcLength = src - aSrc;
  *aDestLength  = dest - aDest;

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function: