summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/base/src/nsCopyMessageStreamListener.cpp
blob: 343c27ac5426f8a12e135e402164fb8d737e04cc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 "nsCopyMessageStreamListener.h"
#include "nsIMsgMailNewsUrl.h"
#include "nsIMsgImapMailFolder.h"
#include "nsIChannel.h"
#include "nsIURI.h"

NS_IMPL_ISUPPORTS(nsCopyMessageStreamListener, nsIStreamListener,
                  nsIRequestObserver, nsICopyMessageStreamListener)

nsCopyMessageStreamListener::nsCopyMessageStreamListener() {}

nsCopyMessageStreamListener::~nsCopyMessageStreamListener() {
  // All member variables are nsCOMPtr's.
}

NS_IMETHODIMP nsCopyMessageStreamListener::Init(
    nsICopyMessageListener* destination) {
  mDestination = destination;
  return NS_OK;
}

NS_IMETHODIMP nsCopyMessageStreamListener::StartMessage() {
  if (mDestination) {
    return mDestination->StartMessage();
  }
  return NS_OK;
}

NS_IMETHODIMP nsCopyMessageStreamListener::EndMessage(nsMsgKey key) {
  if (mDestination) {
    return mDestination->EndMessage(key);
  }
  return NS_OK;
}

NS_IMETHODIMP nsCopyMessageStreamListener::OnDataAvailable(
    nsIRequest* /* request */, nsIInputStream* aIStream, uint64_t sourceOffset,
    uint32_t aLength) {
  return mDestination->CopyData(aIStream, aLength);
}

NS_IMETHODIMP nsCopyMessageStreamListener::OnStartRequest(nsIRequest* request) {
  nsresult rv = NS_OK;
  nsCOMPtr<nsIURI> uri;

  // We know the request is an nsIChannel we can get a URI from, but this is
  // probably bad form. See Bug 1528662.
  nsCOMPtr<nsIChannel> channel = do_QueryInterface(request, &rv);
  NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
                       "error QI nsIRequest to nsIChannel failed");
  if (NS_SUCCEEDED(rv)) rv = channel->GetURI(getter_AddRefs(uri));
  if (NS_SUCCEEDED(rv)) rv = mDestination->BeginCopy();

  NS_ENSURE_SUCCESS(rv, rv);
  return rv;
}

NS_IMETHODIMP nsCopyMessageStreamListener::EndCopy(nsIURI* uri,
                                                   nsresult status) {
  nsresult rv;
  bool copySucceeded = (status == NS_BINDING_SUCCEEDED);
  rv = mDestination->EndCopy(copySucceeded);
  // If this is a move and we finished the copy, delete the old message.
  bool moveMessage = false;

  nsCOMPtr<nsIMsgMailNewsUrl> mailURL(do_QueryInterface(uri));
  if (mailURL) rv = mailURL->IsUrlType(nsIMsgMailNewsUrl::eMove, &moveMessage);

  if (NS_FAILED(rv)) moveMessage = false;

  // OK, this is wrong if we're moving to an imap folder, for example. This
  // really says that we were able to pull the message from the source, NOT that
  // we were able to put it in the destination!
  if (moveMessage) {
    // don't do this if we're moving to an imap folder - that's handled
    // elsewhere.
    nsCOMPtr<nsIMsgImapMailFolder> destImap = do_QueryInterface(mDestination);
    // if the destination is a local folder, it will handle the delete from the
    // source in EndMove
    if (!destImap) rv = mDestination->EndMove(copySucceeded);
  }
  // Even if the above actions failed we probably still want to return NS_OK.
  // There should probably be some error dialog if either the copy or delete
  // failed.
  return NS_OK;
}

NS_IMETHODIMP nsCopyMessageStreamListener::OnStopRequest(nsIRequest* request,
                                                         nsresult aStatus) {
  nsresult rv;
  // We know the request is an nsIChannel we can get a URI from, but this is
  // probably bad form. See Bug 1528662.
  nsCOMPtr<nsIChannel> channel = do_QueryInterface(request, &rv);
  NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
                       "error QI nsIRequest to nsIChannel failed");
  NS_ENSURE_SUCCESS(rv, rv);
  nsCOMPtr<nsIURI> uri;
  rv = channel->GetURI(getter_AddRefs(uri));
  NS_ENSURE_SUCCESS(rv, rv);
  return EndCopy(uri, aStatus);
}