Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions
nsLinebreakConverter.cpp File Reference
#include "nsLinebreakConverter.h"
#include "nsMemory.h"
#include "nsCRT.h"

Go to the source code of this file.

Defines

#define LOSER_CHAR_CAST(t)   (t)
#define LOSER_UNICHAR_CAST(t)   (t)

Functions

static const char * GetLinebreakString (nsLinebreakConverter::ELinebreakType aBreakType)
template<class T >
void AppendLinebreak (T *&ioDest, const char *lineBreakStr)
template<class T >
PRInt32 CountLinebreaks (const T *aSrc, PRInt32 inLen, const char *breakStr)
template<class T >
static TConvertBreaks (const T *inSrc, PRInt32 &ioLen, const char *srcBreak, const char *destBreak)
template<class T >
static void ConvertBreaksInSitu (T *inSrc, PRInt32 inLen, char srcBreak, char destBreak)
template<class T >
static TConvertUnknownBreaks (const T *inSrc, PRInt32 &ioLen, const char *destBreak)

Define Documentation

#define LOSER_CHAR_CAST (   t)    (t)

Definition at line 48 of file nsLinebreakConverter.cpp.

#define LOSER_UNICHAR_CAST (   t)    (t)

Definition at line 49 of file nsLinebreakConverter.cpp.


Function Documentation

template<class T >
void AppendLinebreak ( T *&  ioDest,
const char *  lineBreakStr 
)

Definition at line 80 of file nsLinebreakConverter.cpp.

{
  *ioDest++ = *lineBreakStr;

  if (lineBreakStr[1])
    *ioDest++ = lineBreakStr[1];
}

Here is the caller graph for this function:

template<class T >
static T* ConvertBreaks ( const T inSrc,
PRInt32 ioLen,
const char *  srcBreak,
const char *  destBreak 
) [static]

Definition at line 135 of file nsLinebreakConverter.cpp.

{
  NS_ASSERTION(inSrc && srcBreak && destBreak, "Got a null string");
  
  T* resultString = nsnull;
   
  // handle the no conversion case
  if (nsCRT::strcmp(srcBreak, destBreak) == 0)
  {
    resultString = (T *)nsMemory::Alloc(sizeof(T) * ioLen);
    if (!resultString) return nsnull;
    memcpy(resultString, inSrc, sizeof(T) * ioLen); // includes the null, if any
    return resultString;
  }
    
  PRInt32 srcBreakLen = strlen(srcBreak);
  PRInt32 destBreakLen = strlen(destBreak);

  // handle the easy case, where the string length does not change, and the
  // breaks are only 1 char long, i.e. CR <-> LF
  if (srcBreakLen == destBreakLen && srcBreakLen == 1)
  {
    resultString = (T *)nsMemory::Alloc(sizeof(T) * ioLen);
    if (!resultString) return nsnull;
    
    const T* src = inSrc;
    const T* srcEnd = inSrc + ioLen;             // includes null, if any
    T*       dst = resultString;
    
    char srcBreakChar = *srcBreak;        // we know it's one char long already
    char dstBreakChar = *destBreak;
    
    while (src < srcEnd)
    {
      if (*src == srcBreakChar)
      {
        *dst++ = dstBreakChar;
        src++;
      }
      else
      {
        *dst++ = *src++;
      }
    }

    // ioLen does not change
  }
  else
  {
    // src and dest termination is different length. Do it a slower way.
    
    // count linebreaks in src. Assumes that chars in 2-char linebreaks are unique.
    PRInt32 numLinebreaks = CountLinebreaks(inSrc, ioLen, srcBreak);
    
    PRInt32 newBufLen = ioLen - (numLinebreaks * srcBreakLen) + (numLinebreaks * destBreakLen);
    resultString = (T *)nsMemory::Alloc(sizeof(T) * newBufLen);
    if (!resultString) return nsnull;
    
    const T* src = inSrc;
    const T* srcEnd = inSrc + ioLen;             // includes null, if any
    T*       dst = resultString;
    
    while (src < srcEnd)
    {
      if (*src == *srcBreak)
      {
        *dst++ = *destBreak;
        if (destBreak[1])
          *dst++ = destBreak[1];
      
        src++;
        if (src < srcEnd && srcBreak[1] && *src == srcBreak[1])
          src++;
      }
      else
      {
        *dst++ = *src++;
      }
    }
    
    ioLen = newBufLen;
  }
  
  return resultString;
}

Here is the call graph for this function:

template<class T >
static void ConvertBreaksInSitu ( T inSrc,
PRInt32  inLen,
char  srcBreak,
char  destBreak 
) [static]

Definition at line 229 of file nsLinebreakConverter.cpp.

{
  T* src = inSrc;
  T* srcEnd = inSrc + inLen;

  while (src < srcEnd)
  {
    if (*src == srcBreak)
      *src = destBreak;
    
    src++;
  }
}
template<class T >
static T* ConvertUnknownBreaks ( const T inSrc,
PRInt32 ioLen,
const char *  destBreak 
) [static]

Definition at line 252 of file nsLinebreakConverter.cpp.

{
  const T* src = inSrc;
  const T* srcEnd = inSrc + ioLen;        // includes null, if any
  
  PRInt32 destBreakLen = strlen(destBreak);
  PRInt32 finalLen = 0;

  while (src < srcEnd)
  {
    if (*src == nsCRT::CR)
    {
      if (src < srcEnd && src[1] == nsCRT::LF)
      {
        // CRLF
        finalLen += destBreakLen;
        src++;
      }
      else
      {
        // Lone CR
        finalLen += destBreakLen;
      }
    }
    else if (*src == nsCRT::LF)
    {
      // Lone LF
      finalLen += destBreakLen;
    }
    else
    {
      finalLen++;
    }
    src++;
  }
  
  T* resultString = (T *)nsMemory::Alloc(sizeof(T) * finalLen);
  if (!resultString) return nsnull;

  src = inSrc;
  srcEnd = inSrc + ioLen;          // includes null, if any

  T* dst = resultString;
  
  while (src < srcEnd)
  {
    if (*src == nsCRT::CR)
    {
      if (src < srcEnd && src[1] == nsCRT::LF)
      {
        // CRLF
        AppendLinebreak(dst, destBreak);
        src++;
      }
      else
      {
        // Lone CR
        AppendLinebreak(dst, destBreak);
      }
    }
    else if (*src == nsCRT::LF)
    {
      // Lone LF
      AppendLinebreak(dst, destBreak);
    }
    else
    {
      *dst++ = *src;
    }
    src++;
  }

  ioLen = finalLen;
  return resultString;
}

Here is the call graph for this function:

template<class T >
PRInt32 CountLinebreaks ( const T aSrc,
PRInt32  inLen,
const char *  breakStr 
)

Definition at line 94 of file nsLinebreakConverter.cpp.

{
  const T* src = aSrc;
  const T* srcEnd = aSrc + inLen;
  PRInt32 theCount = 0;

  while (src < srcEnd)
  {
    if (*src == *breakStr)
    {
      src++;

      if (breakStr[1])
      {
        if (src < srcEnd && *src == breakStr[1])
        {
          src++;
          theCount++;
        }
      }
      else
      {
        theCount++;
      }
    }
    else
    {
      src++;
    }
  }
  
  return theCount;
}

Here is the caller graph for this function:

static const char* GetLinebreakString ( nsLinebreakConverter::ELinebreakType  aBreakType) [static]

Definition at line 57 of file nsLinebreakConverter.cpp.

{
  static const char* const sLinebreaks[] = {
    "",             // any
    NS_LINEBREAK,   // platform
    LFSTR,          // content
    CRLF,           // net
    CRSTR,          // Mac
    LFSTR,          // Unix
    CRLF,           // Windows
    nsnull  
  };
  
  return sLinebreaks[aBreakType];
}