Back to index

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

#include <nsMsgFolderCompactor.h>

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

List of all members.

Public Member Functions

NS_DECL_ISUPPORTS
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSICOPYMESSAGESTREAMLISTENER
NS_DECL_NSIURLLISTENER
NS_DECL_NSIMSGFOLDERCOMPACTOR 
nsFolderCompactState (void)
virtual ~nsFolderCompactState (void)
void compact (in nsIMsgFolder aFolder, in boolean aOfflineStore, in nsIMsgWindow aMsgWindow)
void compactAll (in nsISupportsArray aArrayOfFoldersToCompact, in nsIMsgWindow aMsgWindow, in boolean compactOfflineAlso, in nsISupportsArray aOfflineFolderArray)
void onDataAvailable (in nsIRequest aRequest, in nsISupports aContext, in nsIInputStream aInputStream, in unsigned long aOffset, in unsigned long aCount)
 Called when the next chunk of data (corresponding to the request) may be read without blocking the calling thread.
void onStartRequest (in nsIRequest aRequest, in nsISupports aContext)
 Called to signify the beginning of an asynchronous request.
void onStopRequest (in nsIRequest aRequest, in nsISupports aContext, in nsresult aStatusCode)
 Called to signify the end of an asynchronous request.
void Init (in nsIMsgFolder srcFolder, in nsICopyMessageListener destination, in nsISupports listenerData)
void StartMessage ()
void EndMessage (in nsMsgKey key)
void EndCopy (in nsISupports url, in nsresult aStatus)
void OnStartRunningUrl (in nsIURI url)
void OnStopRunningUrl (in nsIURI url, in nsresult aExitCode)

Protected Member Functions

virtual nsresult InitDB (nsIMsgDatabase *db)
virtual nsresult StartCompacting ()
virtual nsresult FinishCompact ()
void CloseOutputStream ()
void CleanupTempFilesAfterError ()
nsresult Init (nsIMsgFolder *aFolder, const char *aBaseMsgUri, nsIMsgDatabase *aDb, nsIFileSpec *aPathSpec, nsIMsgWindow *aMsgWindow)
nsresult GetMessage (nsIMsgDBHdr **message)
nsresult BuildMessageURI (const char *baseURI, PRUint32 key, nsCString &uri)
nsresult ShowStatusMsg (const PRUnichar *aMsg)
nsresult ReleaseFolderLock ()
void ShowCompactingStatusMsg ()
void ShowDoneStatus ()
nsresult CompactNextFolder ()
void AdvanceToNextLine (const char *buffer, PRUint32 &bufferOffset, PRUint32 maxBufferOffset)

Protected Attributes

nsCString m_baseMessageUri
nsCString m_messageUri
nsCOMPtr< nsIMsgFolderm_folder
nsCOMPtr< nsIMsgDatabasem_db
nsFileSpec m_fileSpec
nsOutputFileStreamm_fileStream
nsMsgKeyArray m_keyArray
PRInt32 m_size
PRInt32 m_curIndex
nsMsgKey m_startOfNewMsg
char m_dataBuffer [COMPACTOR_READ_BUFF_SIZE+1]
nsresult m_status
nsCOMPtr< nsIMsgMessageServicem_messageService
nsCOMPtr< nsISupportsArraym_folderArray
nsCOMPtr< nsIMsgWindowm_window
nsCOMPtr< nsIMsgDBHdrm_curSrcHdr
PRUint32 m_folderIndex
PRBool m_compactAll
PRBool m_compactOfflineAlso
PRBool m_compactingOfflineFolders
PRBool m_parsingFolder
PRBool m_needStatusLine
PRBool m_startOfMsg
PRInt32 m_statusOffset
PRInt32 m_addedHeaderSize
nsCOMPtr< nsISupportsArraym_offlineFolderArray

Detailed Description

Definition at line 53 of file nsMsgFolderCompactor.h.


Constructor & Destructor Documentation

Definition at line 86 of file nsMsgFolderCompactor.cpp.

{
  CloseOutputStream();

  if (NS_FAILED(m_status))
  {
    CleanupTempFilesAfterError();
    // if for some reason we failed remove the temp folder and database
  }
}

Here is the call graph for this function:


Member Function Documentation

void nsFolderCompactState::AdvanceToNextLine ( const char *  buffer,
PRUint32 bufferOffset,
PRUint32  maxBufferOffset 
) [protected]

Definition at line 585 of file nsMsgFolderCompactor.cpp.

{
  for (; bufferOffset < maxBufferOffset; bufferOffset++)
  {
    if (buffer[bufferOffset] == nsCRT::CR || buffer[bufferOffset] == nsCRT::LF)
    {
      bufferOffset++;
      if (buffer[bufferOffset- 1] == nsCRT::CR && buffer[bufferOffset] == nsCRT::LF)
        bufferOffset++;
      break;
    }
  }
}
nsresult nsFolderCompactState::BuildMessageURI ( const char *  baseURI,
PRUint32  key,
nsCString uri 
) [protected]

Definition at line 118 of file nsMsgFolderCompactor.cpp.

{
  uri.Append(baseURI);
  uri.Append('#');
  uri.AppendInt(key);
  return NS_OK;
}

Here is the caller graph for this function:

Definition at line 108 of file nsMsgFolderCompactor.cpp.

{
  CloseOutputStream();
  if (m_db)
    m_db->ForceClosed();
  nsLocalFolderSummarySpec summarySpec(m_fileSpec);
  m_fileSpec.Delete(PR_FALSE);
  summarySpec.Delete(PR_FALSE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 97 of file nsMsgFolderCompactor.cpp.

{
  if (m_fileStream)
  {
    m_fileStream->close();
    delete m_fileStream;
    m_fileStream = nsnull;
  }

}

Here is the caller graph for this function:

void nsIMsgFolderCompactor::compact ( in nsIMsgFolder  aFolder,
in boolean  aOfflineStore,
in nsIMsgWindow  aMsgWindow 
) [inherited]
void nsIMsgFolderCompactor::compactAll ( in nsISupportsArray  aArrayOfFoldersToCompact,
in nsIMsgWindow  aMsgWindow,
in boolean  compactOfflineAlso,
in nsISupportsArray  aOfflineFolderArray 
) [inherited]

Definition at line 495 of file nsMsgFolderCompactor.cpp.

{
   nsresult rv = NS_OK;
   m_folderIndex++;
   PRUint32 cnt=0;
   rv = m_folderArray->Count(&cnt);
   NS_ENSURE_SUCCESS(rv,rv);
   if (m_folderIndex == cnt)
   {
     if (m_compactOfflineAlso)
     {
       m_compactingOfflineFolders = PR_TRUE;
       nsCOMPtr<nsIMsgFolder> folder = do_QueryElementAt(m_folderArray,
                                                         m_folderIndex-1, &rv);
       if (NS_SUCCEEDED(rv) && folder)
         folder->CompactAllOfflineStores(m_window, m_offlineFolderArray);
     }
     else
     {
       ShowDoneStatus();
       return rv;
     }
       
   } 
   nsCOMPtr<nsIMsgFolder> folder = do_QueryElementAt(m_folderArray,
                                                     m_folderIndex, &rv);

   if (NS_SUCCEEDED(rv) && folder)
     rv = Compact(folder, m_compactingOfflineFolders, m_window);                    
    else
      ShowDoneStatus();
   return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsICopyMessageStreamListener::EndCopy ( in nsISupports  url,
in nsresult  aStatus 
) [inherited]

Reimplemented in nsOfflineStoreCompactState.

Definition at line 369 of file nsMsgFolderCompactor.cpp.

{
    // All okay time to finish up the compact process
  nsresult rv = NS_OK;
  nsCOMPtr<nsIFileSpec> pathSpec;
  nsCOMPtr<nsIDBFolderInfo> folderInfo;
  nsFileSpec fileSpec;

    // get leaf name and database name of the folder
  rv = m_folder->GetPath(getter_AddRefs(pathSpec));
  pathSpec->GetFileSpec(&fileSpec);

  // need to make sure we put the .msf file in the same directory
  // as the original mailbox, so resolve symlinks.
  PRBool ignored;
  fileSpec.ResolveSymlink(ignored);

  nsLocalFolderSummarySpec summarySpec(fileSpec);
  nsXPIDLCString leafName;
  nsCAutoString dbName(summarySpec.GetLeafName());

  pathSpec->GetLeafName(getter_Copies(leafName));

    // close down the temp file stream; preparing for deleting the old folder
    // and its database; then rename the temp folder and database
  m_fileStream->flush();
  m_fileStream->close();
  delete m_fileStream;
  m_fileStream = nsnull;

  // make sure the new database is valid.
  // Close it so we can rename the .msf file.
  m_db->SetSummaryValid(PR_TRUE);
  m_db->ForceClosed();
  m_db = nsnull;

  nsLocalFolderSummarySpec newSummarySpec(m_fileSpec);

  nsCOMPtr <nsIDBFolderInfo> transferInfo;
  m_folder->GetDBTransferInfo(getter_AddRefs(transferInfo));

  // close down database of the original folder and remove the folder node
  // and all it's message node from the tree
  m_folder->ForceDBClosed();

  PRBool folderRenameSucceeded = PR_FALSE;
  PRBool msfRenameSucceeded = PR_FALSE;
    // remove the old folder and database
  summarySpec.Delete(PR_FALSE);
  if (!summarySpec.Exists())
  {
    fileSpec.Delete(PR_FALSE);
    if (!fileSpec.Exists())
    {
      // rename the copied folder and database to be the original folder and
      // database 
      rv = m_fileSpec.Rename(leafName.get());
      NS_ASSERTION(NS_SUCCEEDED(rv), "error renaming compacted folder");
      if (NS_SUCCEEDED(rv))
      {
        folderRenameSucceeded = PR_TRUE;
        rv = newSummarySpec.Rename(dbName.get());
        NS_ASSERTION(NS_SUCCEEDED(rv), "error renaming compacted folder's db");
        msfRenameSucceeded = NS_SUCCEEDED(rv);
      }
    }
  }
  NS_ASSERTION(msfRenameSucceeded && folderRenameSucceeded, "rename failed in compact");
  if (!folderRenameSucceeded)
    m_fileSpec.Delete(PR_FALSE);
  if (!msfRenameSucceeded)
    newSummarySpec.Delete(PR_FALSE);
  rv = ReleaseFolderLock();
  NS_ASSERTION(NS_SUCCEEDED(rv),"folder lock not released successfully");
  if (msfRenameSucceeded && folderRenameSucceeded)
  {
    m_folder->SetDBTransferInfo(transferInfo);

    nsCOMPtr <nsIDBFolderInfo> dbFolderInfo;

    m_folder->GetDBFolderInfoAndDB(getter_AddRefs(dbFolderInfo), getter_AddRefs(m_db));

    // since we're transferring info from the old db, we need to reset the expunged bytes,
    // and set the summary valid again.
    if(dbFolderInfo)
      dbFolderInfo->SetExpungedBytes(0);
  }
  if (m_db)
    m_db->Close(PR_TRUE);
  m_db = nsnull;

  m_folder->NotifyCompactCompleted();

  if (m_compactAll)
    rv = CompactNextFolder();
  else 
    ShowDoneStatus();
      
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 530 of file nsMsgFolderCompactor.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

void nsICopyMessageStreamListener::Init ( in nsIMsgFolder  srcFolder,
in nsICopyMessageListener  destination,
in nsISupports  listenerData 
) [inherited]
NS_IMETHODIMP nsFolderCompactState::Init ( nsIMsgFolder aFolder,
const char *  aBaseMsgUri,
nsIMsgDatabase aDb,
nsIFileSpec aPathSpec,
nsIMsgWindow aMsgWindow 
) [protected]

Definition at line 278 of file nsMsgFolderCompactor.cpp.

{
  nsresult rv;

  m_folder = folder;
  m_baseMessageUri = baseMsgUri;

  pathSpec->GetFileSpec(&m_fileSpec);

  // need to make sure the temp file goes in the same real directory
  // as the original file, so resolve sym links.
  PRBool ignored;
  m_fileSpec.ResolveSymlink(ignored);

  m_fileSpec.SetLeafName("nstmp");
  m_fileSpec.MakeUnique();   //make sure we are not crunching existing nstmp file
  m_window = aMsgWindow;
  m_keyArray.RemoveAll();
  InitDB(db);

  m_size = m_keyArray.GetSize();
  m_curIndex = 0;
  
  m_fileStream = new nsOutputFileStream(m_fileSpec);
  if (!m_fileStream) 
  {
    m_folder->ThrowAlertMsg("compactFolderWriteFailed", m_window);
    rv = NS_ERROR_OUT_OF_MEMORY; 
  }
  else
  {
    rv = GetMessageServiceFromURI(baseMsgUri,
                                getter_AddRefs(m_messageService));
  }
  if (NS_FAILED(rv))
  {
    m_status = rv;
    Release(); // let go of ourselves...
  }
  return rv;
}

Here is the call graph for this function:

nsresult nsFolderCompactState::InitDB ( nsIMsgDatabase db) [protected, virtual]

Reimplemented in nsOfflineStoreCompactState.

Definition at line 128 of file nsMsgFolderCompactor.cpp.

{
  nsCOMPtr<nsIMsgDatabase> mailDBFactory;
  nsCOMPtr<nsIFileSpec> newPathSpec;

  db->ListAllKeys(m_keyArray);
  nsresult rv = NS_NewFileSpecWithSpec(m_fileSpec, getter_AddRefs(newPathSpec));

  nsCOMPtr<nsIMsgDBService> msgDBService = do_GetService(NS_MSGDB_SERVICE_CONTRACTID, &rv);
  if (msgDBService) 
  {
    nsresult folderOpen = msgDBService->OpenMailDBFromFileSpec(newPathSpec, PR_TRUE,
                                     PR_FALSE,
                                     getter_AddRefs(m_db));

    if(NS_FAILED(folderOpen) &&
       folderOpen == NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE || 
       folderOpen == NS_MSG_ERROR_FOLDER_SUMMARY_MISSING )
    {
      // if it's out of date then reopen with upgrade.
      rv = msgDBService->OpenMailDBFromFileSpec(newPathSpec,
                               PR_TRUE, PR_TRUE,
                               getter_AddRefs(m_db));
    }
  }
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsIStreamListener::onDataAvailable ( in nsIRequest  aRequest,
in nsISupports  aContext,
in nsIInputStream  aInputStream,
in unsigned long  aOffset,
in unsigned long  aCount 
) [inherited]

Called when the next chunk of data (corresponding to the request) may be read without blocking the calling thread.

The onDataAvailable impl must read exactly |aCount| bytes of data before returning.

Parameters:
aRequestrequest corresponding to the source of the data
aContextuser defined context
aInputStreaminput stream containing the data chunk
aOffsetNumber of bytes that were sent in previous onDataAvailable calls for this request. In other words, the sum of all previous count parameters. If that number is greater than or equal to 2^32, this parameter will be PR_UINT32_MAX (2^32 - 1).
aCountnumber of bytes available in the stream

NOTE: The aInputStream parameter must implement readSegments.

An exception thrown from onDataAvailable has the side-effect of causing the request to be canceled.

void nsIRequestObserver::onStartRequest ( in nsIRequest  aRequest,
in nsISupports  aContext 
) [inherited]

Called to signify the beginning of an asynchronous request.

Parameters:
aRequestrequest being observed
aContextuser defined context

An exception thrown from onStartRequest has the side-effect of causing the request to be canceled.

Here is the caller graph for this function:

Here is the caller graph for this function:

void nsIRequestObserver::onStopRequest ( in nsIRequest  aRequest,
in nsISupports  aContext,
in nsresult  aStatusCode 
) [inherited]

Called to signify the end of an asynchronous request.

This call is always preceded by a call to onStartRequest.

Parameters:
aRequestrequest being observed
aContextuser defined context
aStatusCodereason for stopping (NS_OK if completed successfully)

An exception thrown from onStopRequest is generally ignored.

Here is the caller graph for this function:

void nsIUrlListener::OnStopRunningUrl ( in nsIURI  url,
in nsresult  aExitCode 
) [inherited]

Here is the caller graph for this function:

Definition at line 471 of file nsMsgFolderCompactor.cpp.

{
  nsresult result = NS_OK;
  if (!m_folder) return result;
  PRBool haveSemaphore;
  nsCOMPtr <nsISupports> supports = do_QueryInterface(NS_STATIC_CAST(nsIMsgFolderCompactor*, this));
  result = m_folder->TestSemaphore(supports, &haveSemaphore);
  if(NS_SUCCEEDED(result) && haveSemaphore)
    result = m_folder->ReleaseSemaphore(supports);
  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 321 of file nsMsgFolderCompactor.cpp.

{
  nsXPIDLString statusString;
  nsresult rv = m_folder->GetStringWithFolderNameFromBundle("compactingFolder", getter_Copies(statusString));
  if (statusString && NS_SUCCEEDED(rv))
    ShowStatusMsg(statusString);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 483 of file nsMsgFolderCompactor.cpp.

{
  if (m_folder)
  {
    nsXPIDLString statusString;
    nsresult rv = m_folder->GetStringWithFolderNameFromBundle("doneCompacting", getter_Copies(statusString));
    if (statusString && NS_SUCCEEDED(rv))
      ShowStatusMsg(statusString);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 265 of file nsMsgFolderCompactor.cpp.

{
  nsCOMPtr <nsIMsgStatusFeedback> statusFeedback;
  if (m_window)
  {
    m_window->GetStatusFeedback(getter_AddRefs(statusFeedback));
    if (statusFeedback && aMsg)
      return statusFeedback->SetStatusString (aMsg);
  }
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Reimplemented in nsOfflineStoreCompactState.

Definition at line 349 of file nsMsgFolderCompactor.cpp.

{
  nsresult rv = NS_OK;
  if (m_size > 0)
  {
    ShowCompactingStatusMsg();
    AddRef();
    rv = m_messageService->CopyMessages(&m_keyArray, m_folder, this, PR_FALSE, nsnull, m_window, nsnull);
    // m_curIndex = m_size;  // advance m_curIndex to the end - we're done

  }
  else
  { // no messages to copy with
    FinishCompact();
//    Release(); // we don't "own" ourselves yet.
  }
  return rv;
}

Here is the call graph for this function:


Member Data Documentation

Definition at line 112 of file nsMsgFolderCompactor.h.

Definition at line 87 of file nsMsgFolderCompactor.h.

Definition at line 104 of file nsMsgFolderCompactor.h.

Definition at line 106 of file nsMsgFolderCompactor.h.

Definition at line 105 of file nsMsgFolderCompactor.h.

Definition at line 95 of file nsMsgFolderCompactor.h.

Definition at line 102 of file nsMsgFolderCompactor.h.

Definition at line 97 of file nsMsgFolderCompactor.h.

Definition at line 90 of file nsMsgFolderCompactor.h.

Definition at line 91 of file nsMsgFolderCompactor.h.

Definition at line 92 of file nsMsgFolderCompactor.h.

Definition at line 89 of file nsMsgFolderCompactor.h.

Definition at line 100 of file nsMsgFolderCompactor.h.

Definition at line 103 of file nsMsgFolderCompactor.h.

nsMsgKeyArray nsFolderCompactState::m_keyArray [protected]

Definition at line 93 of file nsMsgFolderCompactor.h.

Definition at line 99 of file nsMsgFolderCompactor.h.

Definition at line 88 of file nsMsgFolderCompactor.h.

Definition at line 109 of file nsMsgFolderCompactor.h.

Definition at line 113 of file nsMsgFolderCompactor.h.

Definition at line 107 of file nsMsgFolderCompactor.h.

Definition at line 94 of file nsMsgFolderCompactor.h.

Definition at line 110 of file nsMsgFolderCompactor.h.

Definition at line 96 of file nsMsgFolderCompactor.h.

Definition at line 98 of file nsMsgFolderCompactor.h.

Definition at line 111 of file nsMsgFolderCompactor.h.

Definition at line 101 of file nsMsgFolderCompactor.h.


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