Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes | Static Protected Attributes | Private Member Functions
CMbxScanner Class Reference
Inheritance diagram for CMbxScanner:
Inheritance graph
[legend]
Collaboration diagram for CMbxScanner:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 CMbxScanner (nsString &name, nsIFileSpec *mbxFile, nsIFileSpec *dstFile)
 ~CMbxScanner ()
virtual PRBool Initialize (void)
virtual PRBool DoWork (PRBool *pAbort, PRUint32 *pDone, PRUint32 *pCount)
PRBool WasErrorFatal (void)
PRUint32 BytesProcessed (void)

Public Attributes

PRUint32 m_msgCount

Protected Member Functions

PRBool WriteMailItem (PRUint32 flags, PRUint32 offset, PRUint32 size, PRUint32 *pTotalMsgSize=nsnull)
virtual void CleanUp (void)

Protected Attributes

PRUint32m_pDone
nsString m_name
nsIFileSpecm_mbxFile
nsIFileSpecm_dstFile
PRUint8m_pInBuffer
PRUint8m_pOutBuffer
PRUint32 m_bufSz
PRUint32 m_didBytes
PRBool m_fatalError
PRUint32 m_mbxFileSize
PRUint32 m_mbxOffset

Static Protected Attributes

static const char * m_pFromLine = "From - Mon Jan 1 00:00:00 1965\x0D\x0A"

Private Member Functions

void ReportWriteError (nsIFileSpec *file, PRBool fatal=PR_TRUE)
void ReportReadError (nsIFileSpec *file, PRBool fatal=PR_TRUE)
PRBool CopyMbxFileBytes (PRUint32 flags, PRUint32 numBytes)
PRBool IsFromLineKey (PRUint8 *pBuf, PRUint32 max)

Detailed Description

Definition at line 46 of file nsOEMailbox.cpp.


Constructor & Destructor Documentation

CMbxScanner::CMbxScanner ( nsString name,
nsIFileSpec mbxFile,
nsIFileSpec dstFile 
)

Definition at line 206 of file nsOEMailbox.cpp.

{
  m_msgCount = 0;
  m_name = name;
  m_mbxFile = mbxFile;
  m_mbxFile->AddRef();
  m_dstFile = dstFile;
  m_dstFile->AddRef();
  m_pInBuffer = nsnull;
  m_pOutBuffer = nsnull;
  m_bufSz = 0;
  m_fatalError = PR_FALSE;
  m_didBytes = 0;
  m_mbxFileSize = 0;
  m_mbxOffset = 0;
}

Definition at line 223 of file nsOEMailbox.cpp.

{
       CleanUp();
       if (m_mbxFile)
              m_mbxFile->Release();
       if (m_dstFile)
              m_dstFile->Release();       
}

Here is the call graph for this function:


Member Function Documentation

Definition at line 55 of file nsOEMailbox.cpp.

{ return( m_didBytes);}
void CMbxScanner::CleanUp ( void  ) [protected, virtual]

Reimplemented in CIndexScanner.

Definition at line 297 of file nsOEMailbox.cpp.

{
  m_mbxFile->CloseStream();
  m_dstFile->CloseStream();
  
  if (m_pInBuffer != nsnull) {
    delete [] m_pInBuffer;
    m_pInBuffer = nsnull;
  }
  
  if (m_pOutBuffer != nsnull) {
    delete [] m_pOutBuffer;
    m_pOutBuffer = nsnull;
  }
}

Here is the caller graph for this function:

PRBool CMbxScanner::CopyMbxFileBytes ( PRUint32  flags,
PRUint32  numBytes 
) [private]

Definition at line 363 of file nsOEMailbox.cpp.

{
  if (!numBytes)
    return( PR_TRUE);
  
  PRUint32  cnt;
  PRUint8   last[2] = {0, 0};
  PRUint32  inIdx = 0;
  PRBool    first = PR_TRUE;
  PRUint8 * pIn;
  PRUint8 * pStart;
  PRInt32   fromLen = strlen( m_pFromLine);
  nsresult  rv;
  PRInt32   cntRead;
  PRUint8 * pChar;
  
  while (numBytes) {
    if (numBytes > (m_bufSz - inIdx))
      cnt = m_bufSz - inIdx;
    else
      cnt = numBytes;
    // Read some of the message from the file...
    pChar = m_pInBuffer + inIdx;
    rv = m_mbxFile->Read( (char **) &pChar, (PRInt32)cnt, &cntRead);
    if (NS_FAILED( rv) || (cntRead != (PRInt32)cnt)) {
      ReportReadError( m_mbxFile);
      return( PR_FALSE);
    }
    // Keep track of the last 2 bytes of the message for terminating EOL logic      
    if (cnt < 2) {
      last[0] = last[1];
      last[1] = m_pInBuffer[cnt - 1];
    }
    else {
      last[0] = m_pInBuffer[cnt - 2];
      last[1] = m_pInBuffer[cnt - 1];
    }
    
    inIdx = 0;
    // Handle the beginning line, don't duplicate an existing From separator
    if (first) {
      // check the first buffer to see if it already starts with a From line
      // If it does, throw it away and use our own
      if (IsFromLineKey( m_pInBuffer, cnt)) {
        // skip past the first line
        while ((inIdx < cnt) && (m_pInBuffer[inIdx] != 0x0D))
          inIdx++;
        while ((inIdx < cnt) && (IS_ANY_SPACE( m_pInBuffer[inIdx])))
          inIdx++;
        if (inIdx >= cnt) {
          // This should not occurr - it means the message starts
          // with a From separator line that is longer than our
          // file buffer!  In this bizarre case, just skip this message
          // since it is probably bogus anyway.
          return( PR_TRUE);
        }
        
      }
      // Begin every message with a From separator
      rv = m_dstFile->Write( m_pFromLine, fromLen, &cntRead);
      if (NS_FAILED( rv) || (cntRead != fromLen)) {
        ReportWriteError( m_dstFile);
        return( PR_FALSE);
      }
      char statusLine[50];
      PRUint32 msgFlags = flags; // need to convert from OE flags to mozilla flags
      PR_snprintf(statusLine, sizeof(statusLine), X_MOZILLA_STATUS_FORMAT MSG_LINEBREAK, msgFlags & 0xFFFF);
      rv = m_dstFile->Write(statusLine, strlen(statusLine), &cntRead);
      if (NS_SUCCEEDED(rv) && cntRead == fromLen)
      {
        PR_snprintf(statusLine, sizeof(statusLine), X_MOZILLA_STATUS2_FORMAT MSG_LINEBREAK, msgFlags & 0xFFFF0000);
        rv = m_dstFile->Write(statusLine, strlen(statusLine), &cntRead);
      }
      if (NS_FAILED( rv) || (cntRead != fromLen)) {
        ReportWriteError( m_dstFile);
        return( PR_FALSE);
      }
      first = PR_FALSE;
    }
    
    // Handle generic data, escape any lines that begin with "From "
    pIn = m_pInBuffer + inIdx;
    numBytes -= cnt;
    m_didBytes += cnt;
    pStart = pIn;
    cnt -= inIdx;
    inIdx = 0;
    while (cnt) {
      if (*pIn == 0x0D) {
        // need more in buffer?
        if ((cnt < 7) && numBytes) {
          break;
        }
        else if (cnt > 6) {
          if ((pIn[1] == 0x0A) && (IsFromLineKey( pIn + 2, cnt))) {
            inIdx += 2;
            // Match, escape it
            rv = m_dstFile->Write( (const char *)pStart, (PRInt32)inIdx, &cntRead);
            if (NS_SUCCEEDED( rv) && (cntRead == (PRInt32)inIdx))
              rv = m_dstFile->Write( ">", 1, &cntRead);
            if (NS_FAILED( rv) || (cntRead != 1)) {
              ReportWriteError( m_dstFile);
              return( PR_FALSE);
            }
            cnt -= 2;
            pIn += 2;
            inIdx = 0;
            pStart = pIn;
            continue;
          }
        }
      } // == 0x0D
      cnt--;
      inIdx++;
      pIn++;
    }
    rv = m_dstFile->Write( (const char *)pStart, (PRInt32)inIdx, &cntRead);
    if (NS_FAILED( rv) || (cntRead != (PRInt32)inIdx)) {
      ReportWriteError( m_dstFile);
      return( PR_FALSE);
    }
    if (cnt) {
      inIdx = cnt;
      memcpy( m_pInBuffer, pIn, cnt);
    }
    else
      inIdx = 0;
  }
  
  // I used to check for an eol before writing one but
  // it turns out that adding a proper EOL before the next
  // separator never really hurts so better to be safe
  // and always do it.
  //   if ((last[0] != 0x0D) || (last[1] != 0x0A)) {
  rv = m_dstFile->Write( "\x0D\x0A", 2, &cntRead);
  if (NS_FAILED( rv) || (cntRead != 2)) {
    ReportWriteError( m_dstFile);
    return( PR_FALSE);
  }
  //   }
  
  return( PR_TRUE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool CMbxScanner::DoWork ( PRBool pAbort,
PRUint32 pDone,
PRUint32 pCount 
) [virtual]

Reimplemented in CIndexScanner.

Definition at line 270 of file nsOEMailbox.cpp.

{
  m_mbxOffset = kMbxHeaderSize;
  m_didBytes = kMbxHeaderSize;
  
  while (!(*pAbort) && ((m_mbxOffset + kMbxMessageHeaderSz) < m_mbxFileSize)) {
    PRUint32         msgSz;
    if (!WriteMailItem( 0, m_mbxOffset, 0, &msgSz)) {
      if (!WasErrorFatal())
        ReportReadError( m_mbxFile);
      return( PR_FALSE);
    }
    m_mbxOffset += msgSz;
    m_didBytes += msgSz;
    m_msgCount++;
    if (pDone)
      *pDone = m_didBytes;
    if (pCount)
      *pCount = m_msgCount;
  }
  
  CleanUp();
  
  return( PR_TRUE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Reimplemented in CIndexScanner.

Definition at line 242 of file nsOEMailbox.cpp.

{
  m_bufSz = (kBufferKB * 1024);
  m_pInBuffer = new PRUint8[m_bufSz];
  m_pOutBuffer = new PRUint8[m_bufSz];
  if (!m_pInBuffer || !m_pOutBuffer) {
    return( PR_FALSE);
  }
  
  m_mbxFile->GetFileSize( &m_mbxFileSize);
  // open the mailbox file...
  if (NS_FAILED( m_mbxFile->OpenStreamForReading())) {
    CleanUp();
    return( PR_FALSE);
  }
  
  if (NS_FAILED( m_dstFile->OpenStreamForWriting())) {
    CleanUp();
    return( PR_FALSE);
  }
  
  return( PR_TRUE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool CMbxScanner::IsFromLineKey ( PRUint8 pBuf,
PRUint32  max 
) [private]

Definition at line 354 of file nsOEMailbox.cpp.

{
  return (max > 5 && (pBuf[0] == 'F') && (pBuf[1] == 'r') && (pBuf[2] == 'o') && (pBuf[3] == 'm') && (pBuf[4] == ' '));
}

Here is the caller graph for this function:

void CMbxScanner::ReportReadError ( nsIFileSpec file,
PRBool  fatal = PR_TRUE 
) [private]

Definition at line 237 of file nsOEMailbox.cpp.

{
       m_fatalError = fatal;
}

Here is the caller graph for this function:

void CMbxScanner::ReportWriteError ( nsIFileSpec file,
PRBool  fatal = PR_TRUE 
) [private]

Definition at line 232 of file nsOEMailbox.cpp.

{
       m_fatalError = fatal;
}

Here is the caller graph for this function:

Definition at line 54 of file nsOEMailbox.cpp.

{ return( m_fatalError);}

Here is the caller graph for this function:

PRBool CMbxScanner::WriteMailItem ( PRUint32  flags,
PRUint32  offset,
PRUint32  size,
PRUint32 pTotalMsgSize = nsnull 
) [protected]

Definition at line 316 of file nsOEMailbox.cpp.

{
  PRUint32    values[kNumMbxLongsToRead];
  PRInt32            cnt = kNumMbxLongsToRead * sizeof( PRUint32);
  nsresult    rv;
  PRBool             failed = PR_FALSE;
  PRInt32            cntRead;
  PRInt8 *    pChar = (PRInt8 *) values;
  
  rv = m_mbxFile->Seek( offset);
  m_mbxFile->Failed( &failed);
  
  if (NS_FAILED( rv) || failed) {
    IMPORT_LOG1( "Mbx seek error: 0x%lx\n", offset);
    return( PR_FALSE);
  }
  rv = m_mbxFile->Read( (char **) &pChar, cnt, &cntRead);
  if (NS_FAILED( rv) || (cntRead != cnt)) {
    IMPORT_LOG1( "Mbx read error at: 0x%lx\n", offset);
    return( PR_FALSE);
  }
  if (values[0] != 0x7F007F00) {
    IMPORT_LOG2( "Mbx tag field doesn't match: 0x%lx, at offset: 0x%lx\n", values[0], offset);
    return( PR_FALSE);
  }
  if (size && (values[2] != size)) {
    IMPORT_LOG3( "Mbx size doesn't match idx, mbx: %ld, idx: %ld, at offset: 0x%lx\n", values[2], size, offset);
    return( PR_FALSE);
  }
  
  if (pTotalMsgSize != nsnull)
    *pTotalMsgSize = values[2];
  
  // everything looks kosher...
  // the actual message text follows and is values[3] bytes long...
  return( CopyMbxFileBytes(flags,  values[3]));
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 77 of file nsOEMailbox.cpp.

Definition at line 78 of file nsOEMailbox.cpp.

Definition at line 74 of file nsOEMailbox.cpp.

Definition at line 79 of file nsOEMailbox.cpp.

Definition at line 73 of file nsOEMailbox.cpp.

Definition at line 80 of file nsOEMailbox.cpp.

Definition at line 81 of file nsOEMailbox.cpp.

Definition at line 68 of file nsOEMailbox.cpp.

Definition at line 72 of file nsOEMailbox.cpp.

Definition at line 71 of file nsOEMailbox.cpp.

const char * CMbxScanner::m_pFromLine = "From - Mon Jan 1 00:00:00 1965\x0D\x0A" [static, protected]

Definition at line 83 of file nsOEMailbox.cpp.

Definition at line 75 of file nsOEMailbox.cpp.

Definition at line 76 of file nsOEMailbox.cpp.


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