nsresult nsEudoraMailbox::ImportMailboxUsingTOC( uint32_t *pBytes, bool *pAbort, nsIInputStream *pInputStream, nsIFile *tocFile, nsIMsgFolder *dstFolder, int32_t *pMsgCount) { nsresult rv = NS_OK; int64_t mailSize = m_mailSize; int64_t tocSize = 0; uint32_t saveBytes = pBytes ? *pBytes : 0; nsCOMPtr <nsIInputStream> tocInputStream; rv = tocFile->GetFileSize(&tocSize); // if the index or the mail file is empty then just // use the original mail file. if (!mailSize || !tocSize) return NS_ERROR_FAILURE; rv = NS_NewLocalFileInputStream(getter_AddRefs(tocInputStream), tocFile); NS_ENSURE_SUCCESS(rv, rv); SimpleBufferTonyRCopiedOnce readBuffer; SimpleBufferTonyRCopiedOnce headers; SimpleBufferTonyRCopiedOnce body; SimpleBufferTonyRCopiedOnce copy; int32_t tocOffset = kMsgFirstOffset; EudoraTOCEntry tocEntry; copy.Allocate(kCopyBufferSize); readBuffer.Allocate(kMailReadBufferSize); IMPORT_LOG0("Importing mailbox using TOC: "); DUMP_FILENAME(tocFile, true); nsCOMPtr<nsISeekableStream> tocSeekableStream = do_QueryInterface(tocInputStream); nsCOMPtr<nsISeekableStream> mailboxSeekableStream = do_QueryInterface(pInputStream); nsCOMPtr<nsIOutputStream> outputStream; nsCOMPtr<nsIMsgPluggableStore> msgStore; rv = dstFolder->GetMsgStore(getter_AddRefs(msgStore)); NS_ENSURE_SUCCESS(rv, rv); while (!*pAbort && (tocOffset < (int32_t)tocSize)) { if (NS_FAILED(rv = tocSeekableStream->Seek(nsISeekableStream::NS_SEEK_SET, tocOffset))) break; if (NS_FAILED(rv = ReadTOCEntry(tocInputStream, tocEntry))) break; nsCOMPtr<nsIMsgDBHdr> msgHdr; bool reusable; rv = msgStore->GetNewMsgOutputStream(dstFolder, getter_AddRefs(msgHdr), &reusable, getter_AddRefs(outputStream)); if (NS_FAILED(rv)) break; // Quick and dirty way to read in and parse the message the way the rest // of the code expects. nsCString defaultDate; nsAutoCString bodyType; ReadFileState state; // Seek to the start of the email message. mailboxSeekableStream->Seek(nsISeekableStream::NS_SEEK_SET, tocEntry.m_Offset); // We're fudging the data to make ReadNextMessage happy. In particular // state.size is meant to be the size of the entire file, because it's // assumed that ReadNextMessage will actually have to parse. We know // exactly how big the message is, so we simply set the "size" to be // immediately where the message ends. state.offset = tocEntry.m_Offset; state.pInputStream = pInputStream; state.size = state.offset + tocEntry.m_Length; if (NS_SUCCEEDED(rv = ReadNextMessage(&state, readBuffer, headers, body, defaultDate, bodyType, &tocEntry))) { rv = ImportMessage(headers, body, defaultDate, bodyType, outputStream, pMsgCount); if (pBytes) *pBytes += tocEntry.m_Length; if (NS_SUCCEEDED(rv)) msgStore->FinishNewMessage(outputStream, msgHdr); else { msgStore->DiscardNewMessage(outputStream, msgHdr); IMPORT_LOG0( "*** Error importing message\n"); } } // We currently don't consider an error from ReadNextMessage or ImportMessage to be fatal. // Reset the error back to no error in case this is the last time through the loop. rv = NS_OK; tocOffset += kMsgHeaderSize; if (!reusable) outputStream->Close(); } if (outputStream) outputStream->Close(); if (NS_SUCCEEDED(rv)) { IMPORT_LOG0(" finished\n"); } else { // We failed somewhere important enough that we kept the error. // Bail on all that we imported since we'll be importing everything // again using just the mailbox. IMPORT_LOG0("*** Error importing mailbox using TOC: "); // DUMP_FILENAME(pMail, true); // Reset pBytes back to where it was before we imported this mailbox. // This will likely result in a funky progress bar which will move // backwards, but that's probably the best we can do to keep the // progress accurate since we'll be re-importing the same mailbox. if (pBytes) *pBytes = saveBytes; // Set the message count back to 0. if (pMsgCount) *pMsgCount = 0; } return rv; }
nsresult nsEudoraMailbox::ImportMailboxUsingTOC( PRUint32 *pBytes, PRBool *pAbort, nsIInputStream *pInputStream, nsIFile *tocFile, nsIOutputStream *pDst, PRInt32 *pMsgCount) { nsresult rv = NS_OK; PRInt64 mailSize = m_mailSize; PRInt64 tocSize = 0; PRUint32 saveBytes = pBytes ? *pBytes : 0; nsCOMPtr <nsIInputStream> tocInputStream; rv = tocFile->GetFileSize( &tocSize); // if the index or the mail file is empty then just // use the original mail file. if (!mailSize || !tocSize) return NS_ERROR_FAILURE; rv = NS_NewLocalFileInputStream(getter_AddRefs(tocInputStream), tocFile); NS_ENSURE_SUCCESS(rv, rv); SimpleBufferTonyRCopiedOnce readBuffer; SimpleBufferTonyRCopiedOnce headers; SimpleBufferTonyRCopiedOnce body; SimpleBufferTonyRCopiedOnce copy; PRInt32 tocOffset = kMsgFirstOffset; EudoraTOCEntry tocEntry; copy.Allocate( kCopyBufferSize); readBuffer.Allocate(kMailReadBufferSize); IMPORT_LOG0( "Importing mailbox using TOC: "); DUMP_FILENAME( tocFile, PR_TRUE); nsCOMPtr <nsISeekableStream> tocSeekableStream = do_QueryInterface(tocInputStream); nsCOMPtr <nsISeekableStream> mailboxSeekableStream = do_QueryInterface(pInputStream); while (!*pAbort && (tocOffset < (PRInt32)tocSize)) { if ( NS_FAILED(rv = tocSeekableStream->Seek(nsISeekableStream::NS_SEEK_SET, tocOffset)) ) break; if ( NS_FAILED(rv = ReadTOCEntry(tocInputStream, tocEntry)) ) break; // Quick and dirty way to read in and parse the message the way the rest // of the code expects. nsCString defaultDate; nsCAutoString bodyType; ReadFileState state; // Seek to the start of the email message. mailboxSeekableStream->Seek(nsISeekableStream::NS_SEEK_SET, tocEntry.m_Offset); // We're fudging the data to make ReadNextMessage happy. In particular // state.size is meant to be the size of the entire file, because it's // assumed that ReadNextMessage will actually have to parse. We know // exactly how big the message is, so we simply set the "size" to be // immediately where the message ends. state.offset = tocEntry.m_Offset; state.pInputStream = pInputStream; state.size = state.offset + tocEntry.m_Length; if ( NS_SUCCEEDED(rv = ReadNextMessage(&state, readBuffer, headers, body, defaultDate, bodyType, &tocEntry) ) ) { rv = ImportMessage(headers, body, defaultDate, bodyType, pDst, pMsgCount); if (pBytes) *pBytes += tocEntry.m_Length; } // We currently don't consider an error from ReadNextMessage or ImportMessage to be fatal. // Reset the error back to no error in case this is the last time through the loop. rv = NS_OK; tocOffset += kMsgHeaderSize; } if ( NS_SUCCEEDED(rv) ) { IMPORT_LOG0( " finished\n"); } else { // We failed somewhere important enough that we kept the error. // Bail on all that we imported since we'll be importing everything // again using just the mailbox. IMPORT_LOG0( "*** Error importing mailbox using TOC: "); // DUMP_FILENAME(pMail, PR_TRUE); // Close the destination and truncate it. We don't need to bother // to reopen it because the nsIFileSpec implementation will open // before writing if necessary (and yes legacy importing code already // relies on this behavior). // pDst->CloseStream(); // pDst->Truncate(0); // Reset pBytes back to where it was before we imported this mailbox. // This will likely result in a funky progress bar which will move // backwards, but that's probably the best we can do to keep the // progress accurate since we'll be re-importing the same mailbox. if (pBytes) *pBytes = saveBytes; // Set the message count back to 0. if (pMsgCount) *pMsgCount = 0; } return rv; }