Bug 1562158 - Remove xpidl [array] use from nsIImapMailFolderSink. r=jorgk
authorBen Campbell <benc@thunderbird.net>
Thu, 26 Sep 2019 13:53:44 +1200
changeset 37079 5fcde2aba579886c6c1598314ec65211023e7d85
parent 37078 6ff5305dadb925e7904cb5d4a3368a473d46cc95
child 37080 f47342bf3567fd2f36c92b63127a3f6032a30b8e
push id395
push userclokep@gmail.com
push dateMon, 02 Dec 2019 19:38:57 +0000
reviewersjorgk
bugs1562158
Bug 1562158 - Remove xpidl [array] use from nsIImapMailFolderSink. r=jorgk
mailnews/imap/public/nsIImapMailFolderSink.idl
mailnews/imap/public/nsIImapProtocol.idl
mailnews/imap/src/nsImapMailFolder.cpp
mailnews/imap/src/nsImapProtocol.cpp
mailnews/imap/src/nsImapProtocol.h
mailnews/imap/src/nsSyncRunnableHelpers.cpp
--- a/mailnews/imap/public/nsIImapMailFolderSink.idl
+++ b/mailnews/imap/public/nsIImapMailFolderSink.idl
@@ -65,18 +65,17 @@ interface nsIImapMailFolderSink : nsISup
   /**
    * Used when downloading headers in chunks.
    * @param aSpec Mailbox spec of folder we're downloading headers for.
    * @returns true if more to download, false otherwise.
    * @returns total count of headers to download (across all chunks)
    * @returns an array of msg keys to download, array size is this chunk's size
    */
   void getMsgHdrsToDownload(out boolean aMore, out long aTotalCount,
-                            out unsigned long aCount,
-                            [retval, array, size_is(aCount)] out nsMsgKey aKeys);
+                            out Array<nsMsgKey> aKeys);
   void parseMsgHdrs(in nsIImapProtocol aProtocol, in nsIImapHeaderXferInfo aHdrXferInfo);
   void AbortHeaderParseStream(in nsIImapProtocol aProtocol) ;
 
   void OnlineCopyCompleted(in nsIImapProtocol aProtocol, in ImapOnlineCopyState aCopyState);
   void StartMessage(in nsIMsgMailNewsUrl aUrl);
   void EndMessage(in nsIMsgMailNewsUrl aUrl, in nsMsgKey uidOfMessage);
 
   void NotifySearchHit(in nsIMsgMailNewsUrl aUrl, in string hitLine);
--- a/mailnews/imap/public/nsIImapProtocol.idl
+++ b/mailnews/imap/public/nsIImapProtocol.idl
@@ -1,14 +1,15 @@
 /* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
+#include "MailNewsTypes2.idl"  // for nsMsgKey
 
 interface nsIURI;
 interface nsIImapUrl;
 interface nsIImapIncomingServer;
 interface nsIMsgFolder;
 interface nsIMsgWindow;
 interface nsIImapFlagAndUidState;
 
@@ -39,17 +40,18 @@ interface nsIImapProtocol : nsISupports 
 
   /**
    * Initialize a protocol object.
    * @param aHostSessionList host session list service
    * @param aServer imap server the protocol object will be talking to
    */
   void Initialize(in nsIImapHostSessionList aHostSessionList, in nsIImapIncomingServer aServer);
 
-  void NotifyBodysToDownload(out unsigned long keys, in unsigned long count);
+  void NotifyBodysToDownload(in Array<nsMsgKey> keys);
+
   // methods to get data from the imap parser flag state.
   void GetFlagsForUID(in unsigned long uid, out boolean foundIt, out unsigned short flags, out string customFlags);
   void GetSupportedUserFlags(out unsigned short flags);
 
   void GetRunningImapURL(out nsIImapUrl aImapUrl);
 
   void GetRunningUrl(out nsIURI aUrl);
 
--- a/mailnews/imap/src/nsImapMailFolder.cpp
+++ b/mailnews/imap/src/nsImapMailFolder.cpp
@@ -4031,29 +4031,25 @@ void nsImapMailFolder::FindKeysToAdd(con
         }
         keysToFetch.AppendElement(uidOfMessage);
         if (!(flags & kImapMsgSeenFlag)) numNewUnread++;
       }
     }
   }
 }
 
-NS_IMETHODIMP nsImapMailFolder::GetMsgHdrsToDownload(bool *aMoreToDownload,
-                                                     int32_t *aTotalCount,
-                                                     uint32_t *aLength,
-                                                     nsMsgKey **aKeys) {
+NS_IMETHODIMP nsImapMailFolder::GetMsgHdrsToDownload(
+    bool *aMoreToDownload, int32_t *aTotalCount, nsTArray<nsMsgKey> &aKeys) {
   NS_ENSURE_ARG_POINTER(aMoreToDownload);
   NS_ENSURE_ARG_POINTER(aTotalCount);
-  NS_ENSURE_ARG_POINTER(aLength);
-  NS_ENSURE_ARG_POINTER(aKeys);
+  aKeys.Clear();
 
   *aMoreToDownload = false;
   *aTotalCount = m_totalKeysToFetch;
   if (m_keysToFetch.IsEmpty()) {
-    *aLength = 0;
     return NS_OK;
   }
 
   // if folder isn't open in a window, no reason to limit the number of headers
   // we download.
   nsCOMPtr<nsIMsgMailSession> session =
       do_GetService(NS_MSGMAILSESSION_CONTRACTID);
   bool folderOpen = false;
@@ -4071,30 +4067,28 @@ NS_IMETHODIMP nsImapMailFolder::GetMsgHd
   int32_t numKeysToFetch = m_keysToFetch.Length();
   int32_t startIndex = 0;
   if (folderOpen && hdrChunkSize > 0 &&
       (int32_t)m_keysToFetch.Length() > hdrChunkSize) {
     numKeysToFetch = hdrChunkSize;
     *aMoreToDownload = true;
     startIndex = m_keysToFetch.Length() - hdrChunkSize;
   }
-  *aKeys = (nsMsgKey *)moz_xmemdup(&m_keysToFetch[startIndex],
-                                   numKeysToFetch * sizeof(nsMsgKey));
-  NS_ENSURE_TRUE(*aKeys, NS_ERROR_OUT_OF_MEMORY);
+  aKeys.AppendElements(&m_keysToFetch[startIndex], numKeysToFetch);
   // Remove these for the incremental header download case, so that
   // we know we don't have to download them again.
   m_keysToFetch.RemoveElementsAt(startIndex, numKeysToFetch);
-  *aLength = numKeysToFetch;
 
   return NS_OK;
 }
 
 void nsImapMailFolder::PrepareToAddHeadersToMailDB(nsIImapProtocol *aProtocol) {
   // now, tell it we don't need any bodies.
-  aProtocol->NotifyBodysToDownload(nullptr, 0);
+  nsTArray<nsMsgKey> noBodies;
+  aProtocol->NotifyBodysToDownload(noBodies);
 }
 
 void nsImapMailFolder::TweakHeaderFlags(nsIImapProtocol *aProtocol,
                                         nsIMsgDBHdr *tweakMe) {
   if (mDatabase && aProtocol && tweakMe) {
     tweakMe->SetMessageKey(m_curMsgUid);
     tweakMe->SetMessageSize(m_nextMessageByteLength);
 
@@ -5455,32 +5449,33 @@ nsImapMailFolder::HeaderFetchCompleted(n
     if (m_downloadingFolderForOfflineUse || autoSyncOfflineStores ||
         autoDownloadNewHeaders) {
       nsTArray<nsMsgKey> keysToDownload;
       GetBodysToDownload(&keysToDownload);
       // this is the case when DownloadAllForOffline is called.
       if (!keysToDownload.IsEmpty() &&
           (m_downloadingFolderForOfflineUse || autoDownloadNewHeaders)) {
         notifiedBodies = true;
-        aProtocol->NotifyBodysToDownload(keysToDownload.Elements(),
-                                         keysToDownload.Length());
+        aProtocol->NotifyBodysToDownload(keysToDownload);
       } else {
         // create auto-sync state object lazily
         InitAutoSyncState();
 
         // make enough room for new downloads
         m_autoSyncStateObj->ManageStorageSpace();
         m_autoSyncStateObj->SetServerCounts(
             m_numServerTotalMessages, m_numServerRecentMessages,
             m_numServerUnseenMessages, m_nextUID);
         m_autoSyncStateObj->OnNewHeaderFetchCompleted(keysToDownload);
       }
     }
-    if (!notifiedBodies)
-      aProtocol->NotifyBodysToDownload(nullptr, 0 /*keysToFetch.Length() */);
+    if (!notifiedBodies) {
+      nsTArray<nsMsgKey> noBodies;
+      aProtocol->NotifyBodysToDownload(noBodies);
+    }
 
     nsCOMPtr<nsIURI> runningUri;
     aProtocol->GetRunningUrl(getter_AddRefs(runningUri));
     if (runningUri) {
       nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(runningUri);
       if (mailnewsUrl) mailnewsUrl->GetMsgWindow(getter_AddRefs(msgWindow));
     }
   }
--- a/mailnews/imap/src/nsImapProtocol.cpp
+++ b/mailnews/imap/src/nsImapProtocol.cpp
@@ -469,17 +469,16 @@ nsImapProtocol::nsImapProtocol()
   m_ignoreExpunges = false;
   m_prefAuthMethods = kCapabilityUndefined;
   m_failedAuthMethods = 0;
   m_currentAuthMethod = kCapabilityUndefined;
   m_socketType = nsMsgSocketType::trySTARTTLS;
   m_connectionStatus = NS_OK;
   m_safeToCloseConnection = false;
   m_hostSessionList = nullptr;
-  m_fetchBodyIdList = nullptr;
   m_isGmailServer = false;
   m_fetchingWholeMessage = false;
 
   nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID));
   NS_ASSERTION(prefBranch, "FAILED to create the preference service");
 
   // read in the accept languages preference
   if (prefBranch) {
@@ -648,18 +647,16 @@ nsImapProtocol::Initialize(nsIImapHostSe
       return rv;
     }
     m_iThread->GetPRThread(&m_thread);
   }
   return NS_OK;
 }
 
 nsImapProtocol::~nsImapProtocol() {
-  PR_Free(m_fetchBodyIdList);
-
   PR_Free(m_dataOutputBuf);
 
   // **** We must be out of the thread main loop function
   NS_ASSERTION(!m_imapThreadIsRunning, "Oops, thread is still running.");
 }
 
 const nsCString &nsImapProtocol::GetImapHostName() {
   if (m_runningUrl && m_hostName.IsEmpty()) {
@@ -2431,24 +2428,22 @@ void nsImapProtocol::ProcessSelectedStat
                       .GetSelectedMailboxName()) {  // why are we in the
                                                     // selected state with no
                                                     // box name?
         SelectMailbox(mailboxName.get());
         selectIssued = true;
       } else if (moreHeadersToDownload &&
                  m_imapMailFolderSink)  // we need to fetch older headers
       {
-        nsMsgKey *msgIdList = nullptr;
-        uint32_t msgCount = 0;
+        nsTArray<nsMsgKey> msgIdList;
         bool more;
         m_imapMailFolderSink->GetMsgHdrsToDownload(
-            &more, &m_progressExpectedNumber, &msgCount, &msgIdList);
-        if (msgIdList) {
-          FolderHeaderDump(msgIdList, msgCount);
-          free(msgIdList);
+            &more, &m_progressExpectedNumber, msgIdList);
+        if (msgIdList.Length() > 0) {
+          FolderHeaderDump(msgIdList.Elements(), msgIdList.Length());
           m_runningUrl->SetMoreHeadersToDownload(more);
           // We're going to be re-running this url.
           if (more) m_runningUrl->SetRerunningUrl(true);
         }
         HeaderFetchCompleted();
       } else {
         // get new message counts, if any, from server
         if (m_needNoop) {
@@ -4193,74 +4188,73 @@ void nsImapProtocol::ProcessMailboxUpdat
     nsImapAction imapAction;
     nsresult res = m_runningUrl->GetImapAction(&imapAction);
     if (NS_SUCCEEDED(res) && imapAction == nsIImapUrl::nsImapLiteSelectFolder)
       return;
   }
 
   bool entered_waitForBodyIdsMonitor = false;
 
-  uint32_t *msgIdList = nullptr;
-  uint32_t msgCount = 0;
+  nsTArray<nsMsgKey> msgIdList;
 
   RefPtr<nsImapMailboxSpec> new_spec =
       GetServerStateParser().CreateCurrentMailboxSpec();
   if (new_spec && GetServerStateParser().LastCommandSuccessful()) {
     nsImapAction imapAction;
     nsresult res = m_runningUrl->GetImapAction(&imapAction);
     if (NS_SUCCEEDED(res) && imapAction == nsIImapUrl::nsImapExpungeFolder)
       new_spec->mBoxFlags |= kJustExpunged;
     m_waitForBodyIdsMonitor.Enter();
     entered_waitForBodyIdsMonitor = true;
 
     if (m_imapMailFolderSink) {
       bool more;
       m_imapMailFolderSink->UpdateImapMailboxInfo(this, new_spec);
       m_imapMailFolderSink->GetMsgHdrsToDownload(
-          &more, &m_progressExpectedNumber, &msgCount, &msgIdList);
+          &more, &m_progressExpectedNumber, msgIdList);
       // Assert that either it's empty string OR it must be header string.
       MOZ_ASSERT((m_stringIndex == IMAP_EMPTY_STRING_INDEX) ||
                  (m_stringIndex == IMAP_HEADERS_STRING_INDEX));
       m_progressCurrentNumber[m_stringIndex] = 0;
       m_runningUrl->SetMoreHeadersToDownload(more);
       // We're going to be re-running this url if there are more headers.
       if (more) m_runningUrl->SetRerunningUrl(true);
     }
   }
 
   if (GetServerStateParser().LastCommandSuccessful()) {
     if (entered_waitForBodyIdsMonitor) m_waitForBodyIdsMonitor.Exit();
 
-    if (msgIdList && !DeathSignalReceived() &&
+    if (msgIdList.Length() > 0 && !DeathSignalReceived() &&
         GetServerStateParser().LastCommandSuccessful()) {
-      FolderHeaderDump(msgIdList, msgCount);
-      free(msgIdList);
+      FolderHeaderDump(msgIdList.Elements(), msgIdList.Length());
     }
     HeaderFetchCompleted();
     // this might be bogus, how are we going to do pane notification and stuff
     // when we fetch bodies without headers!
   } else if (entered_waitForBodyIdsMonitor)  // need to exit this monitor if
                                              // death signal received
     m_waitForBodyIdsMonitor.Exit();
 
   // wait for a list of bodies to fetch.
   if (GetServerStateParser().LastCommandSuccessful()) {
-    WaitForPotentialListOfBodysToFetch(&msgIdList, msgCount);
-    if (msgCount && GetServerStateParser().LastCommandSuccessful()) {
+    nsTArray<nsMsgKey> msgIds;
+    WaitForPotentialListOfBodysToFetch(msgIds);
+    if (msgIds.Length() > 0 && GetServerStateParser().LastCommandSuccessful()) {
       // Tell the url that it should store the msg fetch results offline,
       // while we're dumping the messages, and then restore the setting.
       bool wasStoringOffline;
       m_runningUrl->GetStoreResultsOffline(&wasStoringOffline);
       m_runningUrl->SetStoreResultsOffline(true);
       // Assert that either it's empty string OR it must be message string.
       MOZ_ASSERT((m_stringIndex == IMAP_EMPTY_STRING_INDEX) ||
                  (m_stringIndex == IMAP_MESSAGES_STRING_INDEX));
       m_progressCurrentNumber[m_stringIndex] = 0;
-      m_progressExpectedNumber = msgCount;
-      FolderMsgDump(msgIdList, msgCount, kEveryThingRFC822Peek);
+      m_progressExpectedNumber = msgIds.Length();
+      FolderMsgDump(msgIds.Elements(), msgIds.Length(), kEveryThingRFC822Peek);
       m_runningUrl->SetStoreResultsOffline(wasStoringOffline);
     }
   }
   if (!GetServerStateParser().LastCommandSuccessful())
     GetServerStateParser().ResetFlagInfo();
 }
 
 void nsImapProtocol::FolderHeaderDump(uint32_t *msgUids, uint32_t msgCount) {
@@ -4282,39 +4276,34 @@ void nsImapProtocol::FolderMsgDump(uint3
       break;
   }
 
   FolderMsgDumpLoop(msgUids, msgCount, fields);
 
   SetProgressString(IMAP_EMPTY_STRING_INDEX);
 }
 
-void nsImapProtocol::WaitForPotentialListOfBodysToFetch(uint32_t **msgIdList,
-                                                        uint32_t &msgCount) {
+void nsImapProtocol::WaitForPotentialListOfBodysToFetch(
+    nsTArray<nsMsgKey> &msgIdList) {
   PRIntervalTime sleepTime = kImapSleepTime;
 
   ReentrantMonitorAutoEnter fetchListMon(m_fetchBodyListMonitor);
   while (!m_fetchBodyListIsNew && !DeathSignalReceived())
     fetchListMon.Wait(sleepTime);
   m_fetchBodyListIsNew = false;
 
-  *msgIdList = m_fetchBodyIdList;
-  msgCount = m_fetchBodyCount;
+  msgIdList = m_fetchBodyIdList;
 }
 
 // libmsg uses this to notify a running imap url about message bodies it should
 // download. why not just have libmsg explicitly download the message bodies?
-NS_IMETHODIMP nsImapProtocol::NotifyBodysToDownload(uint32_t *keys,
-                                                    uint32_t keyCount) {
+NS_IMETHODIMP nsImapProtocol::NotifyBodysToDownload(
+    const nsTArray<nsMsgKey> &keys) {
   ReentrantMonitorAutoEnter fetchListMon(m_fetchBodyListMonitor);
-  PR_FREEIF(m_fetchBodyIdList);
-  m_fetchBodyIdList = (uint32_t *)PR_MALLOC(keyCount * sizeof(uint32_t));
-  if (m_fetchBodyIdList)
-    memcpy(m_fetchBodyIdList, keys, keyCount * sizeof(uint32_t));
-  m_fetchBodyCount = keyCount;
+  m_fetchBodyIdList = keys;
   m_fetchBodyListIsNew = true;
   fetchListMon.Notify();
   return NS_OK;
 }
 
 NS_IMETHODIMP nsImapProtocol::GetFlagsForUID(uint32_t uid, bool *foundIt,
                                              imapMessageFlagsType *resultFlags,
                                              char **customFlags) {
--- a/mailnews/imap/src/nsImapProtocol.h
+++ b/mailnews/imap/src/nsImapProtocol.h
@@ -443,32 +443,30 @@ class nsImapProtocol : public nsIImapPro
   void SendSetBiffIndicatorEvent(nsMsgBiffState newState);
 
   // folder opening and listing header functions
   void FolderHeaderDump(uint32_t *msgUids, uint32_t msgCount);
   void FolderMsgDump(uint32_t *msgUids, uint32_t msgCount,
                      nsIMAPeFetchFields fields);
   void FolderMsgDumpLoop(uint32_t *msgUids, uint32_t msgCount,
                          nsIMAPeFetchFields fields);
-  void WaitForPotentialListOfBodysToFetch(uint32_t **msgIdList,
-                                          uint32_t &msgCount);
+  void WaitForPotentialListOfBodysToFetch(nsTArray<nsMsgKey> &msgIdList);
   void HeaderFetchCompleted();
   void UploadMessageFromFile(nsIFile *file, const char *mailboxName,
                              PRTime date, imapMessageFlagsType flags,
                              nsCString &keywords);
 
   // mailbox name utilities.
   void CreateEscapedMailboxName(const char *rawName, nsCString &escapedName);
   void SetupMessageFlagsString(nsCString &flagString,
                                imapMessageFlagsType flags, uint16_t userFlags);
 
   // body fetching listing data
   bool m_fetchBodyListIsNew;
-  uint32_t m_fetchBodyCount;
-  uint32_t *m_fetchBodyIdList;
+  nsTArray<nsMsgKey> m_fetchBodyIdList;
 
   // initialization function given a new url and transport layer
   nsresult SetupWithUrl(nsIURI *aURL, nsISupports *aConsumer);
   nsresult SetupWithUrlCallback(nsIProxyInfo *proxyInfo);
   void ReleaseUrlState(bool rerunningUrl);  // release any state that is stored
                                             // on a per action basis.
   /**
    * Last ditch effort to run the url without using an imap connection.
--- a/mailnews/imap/src/nsSyncRunnableHelpers.cpp
+++ b/mailnews/imap/src/nsSyncRunnableHelpers.cpp
@@ -334,18 +334,18 @@ NS_SYNCRUNNABLEMETHOD3(ImapMailFolderSin
                        const nsACString &, uint32_t, uint32_t)
 NS_SYNCRUNNABLEMETHOD1(ImapMailFolderSink, GetShouldDownloadAllHeaders, bool *)
 NS_SYNCRUNNABLEMETHOD1(ImapMailFolderSink, GetOnlineDelimiter, char *)
 NS_SYNCRUNNABLEMETHOD0(ImapMailFolderSink, OnNewIdleMessages)
 NS_SYNCRUNNABLEMETHOD2(ImapMailFolderSink, UpdateImapMailboxStatus,
                        nsIImapProtocol *, nsIMailboxSpec *)
 NS_SYNCRUNNABLEMETHOD2(ImapMailFolderSink, UpdateImapMailboxInfo,
                        nsIImapProtocol *, nsIMailboxSpec *)
-NS_SYNCRUNNABLEMETHOD4(ImapMailFolderSink, GetMsgHdrsToDownload, bool *,
-                       int32_t *, uint32_t *, nsMsgKey **)
+NS_SYNCRUNNABLEMETHOD3(ImapMailFolderSink, GetMsgHdrsToDownload, bool *,
+                       int32_t *, nsTArray<nsMsgKey> &)
 NS_SYNCRUNNABLEMETHOD2(ImapMailFolderSink, ParseMsgHdrs, nsIImapProtocol *,
                        nsIImapHeaderXferInfo *)
 NS_SYNCRUNNABLEMETHOD1(ImapMailFolderSink, AbortHeaderParseStream,
                        nsIImapProtocol *)
 NS_SYNCRUNNABLEMETHOD2(ImapMailFolderSink, OnlineCopyCompleted,
                        nsIImapProtocol *, ImapOnlineCopyState)
 NS_SYNCRUNNABLEMETHOD1(ImapMailFolderSink, StartMessage, nsIMsgMailNewsUrl *)
 NS_SYNCRUNNABLEMETHOD2(ImapMailFolderSink, EndMessage, nsIMsgMailNewsUrl *,