~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/modules/libpr0n/src/imgRequestProxy.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 
2
 *
 
3
 * The contents of this file are subject to the Mozilla Public
 
4
 * License Version 1.1 (the "License"); you may not use this file
 
5
 * except in compliance with the License. You may obtain a copy of
 
6
 * the License at http://www.mozilla.org/MPL/
 
7
 * 
 
8
 * Software distributed under the License is distributed on an "AS
 
9
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 
10
 * implied. See the License for the specific language governing
 
11
 * rights and limitations under the License.
 
12
 * 
 
13
 * The Original Code is mozilla.org code.
 
14
 * 
 
15
 * The Initial Developer of the Original Code is Netscape
 
16
 * Communications Corporation.  Portions created by Netscape are
 
17
 * Copyright (C) 2001 Netscape Communications Corporation.
 
18
 * All Rights Reserved.
 
19
 * 
 
20
 * Contributor(s):
 
21
 *   Stuart Parmenter <pavlov@netscape.com>
 
22
 */
 
23
 
 
24
#include "imgRequestProxy.h"
 
25
 
 
26
#include "nsIInputStream.h"
 
27
#include "nsIComponentManager.h"
 
28
#include "nsIServiceManager.h"
 
29
 
 
30
#include "nsAutoLock.h"
 
31
#include "nsString.h"
 
32
#include "nsXPIDLString.h"
 
33
#include "nsReadableUtils.h"
 
34
#include "nsCRT.h"
 
35
 
 
36
#include "ImageErrors.h"
 
37
#include "ImageLogging.h"
 
38
 
 
39
#include "nspr.h"
 
40
 
 
41
 
 
42
NS_IMPL_THREADSAFE_ISUPPORTS2(imgRequestProxy, imgIRequest, nsIRequest)
 
43
 
 
44
imgRequestProxy::imgRequestProxy() :
 
45
  mOwner(nsnull),
 
46
  mListener(nsnull),
 
47
  mLoadFlags(nsIRequest::LOAD_NORMAL),
 
48
  mCanceled(PR_FALSE),
 
49
  mIsInLoadGroup(PR_FALSE),
 
50
  mLock(nsnull)
 
51
{
 
52
  /* member initializers and constructor code */
 
53
 
 
54
  mLock = PR_NewLock();
 
55
}
 
56
 
 
57
imgRequestProxy::~imgRequestProxy()
 
58
{
 
59
  /* destructor code */
 
60
  NS_PRECONDITION(!mListener, "Someone forgot to properly cancel this request!");
 
61
 
 
62
  if (mOwner) {
 
63
    if (!mCanceled) {
 
64
      PR_Lock(mLock);
 
65
 
 
66
      mCanceled = PR_TRUE;
 
67
 
 
68
      /* set mListener to null so that we don't forward any callbacks that
 
69
         RemoveProxy might generate
 
70
       */
 
71
      mListener = nsnull;
 
72
 
 
73
      PR_Unlock(mLock);
 
74
 
 
75
      /* Call RemoveProxy with a successful status.  This will keep the
 
76
         channel, if still downloading data, from being canceled if 'this' is
 
77
         the last observer.  This allows the image to continue to download and
 
78
         be cached even if no one is using it currently.
 
79
       */
 
80
      mOwner->RemoveProxy(this, NS_OK, PR_FALSE);
 
81
    }
 
82
 
 
83
    NS_RELEASE(mOwner);
 
84
  }
 
85
 
 
86
  PR_DestroyLock(mLock);
 
87
}
 
88
 
 
89
 
 
90
 
 
91
nsresult imgRequestProxy::Init(imgRequest *request, nsILoadGroup *aLoadGroup, imgIDecoderObserver *aObserver)
 
92
{
 
93
  NS_PRECONDITION(request, "no request");
 
94
  if (!request)
 
95
    return NS_ERROR_NULL_POINTER;
 
96
 
 
97
  LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequestProxy::Init", "request", request);
 
98
 
 
99
  PR_Lock(mLock);
 
100
 
 
101
  mOwner = request;
 
102
  NS_ADDREF(mOwner);
 
103
 
 
104
  mListener = aObserver;
 
105
 
 
106
  mLoadGroup = aLoadGroup;
 
107
 
 
108
  PR_Unlock(mLock);
 
109
 
 
110
  request->AddProxy(this, PR_FALSE); // Pass PR_FALSE here so that AddProxy doesn't send all the On* notifications immediatly
 
111
 
 
112
  return NS_OK;
 
113
}
 
114
 
 
115
nsresult imgRequestProxy::ChangeOwner(imgRequest *aNewOwner)
 
116
{
 
117
  if (mCanceled)
 
118
    return NS_OK;
 
119
 
 
120
  PR_Lock(mLock);
 
121
 
 
122
  mOwner->RemoveProxy(this, NS_IMAGELIB_CHANGING_OWNER, PR_FALSE);
 
123
  NS_RELEASE(mOwner);
 
124
 
 
125
  mOwner = aNewOwner;
 
126
  NS_ADDREF(mOwner);
 
127
 
 
128
  mOwner->AddProxy(this, PR_FALSE);
 
129
 
 
130
  PR_Unlock(mLock);
 
131
 
 
132
  return NS_OK;
 
133
}
 
134
 
 
135
void imgRequestProxy::AddToLoadGroup()
 
136
{
 
137
  NS_ASSERTION(!mIsInLoadGroup, "Whaa, we're already in the loadgroup!");
 
138
 
 
139
  if (!mIsInLoadGroup && mLoadGroup) {
 
140
    mLoadGroup->AddRequest(this, nsnull);
 
141
    mIsInLoadGroup = PR_TRUE;
 
142
  }
 
143
}
 
144
 
 
145
void imgRequestProxy::RemoveFromLoadGroup()
 
146
{
 
147
  if (!mIsInLoadGroup)
 
148
    return;
 
149
 
 
150
  /* calling RemoveFromLoadGroup may cause the document to finish
 
151
     loading, which could result in our death.  We need to make sure
 
152
     that we stay alive long enough to fight another battle... at
 
153
     least until we exit this function.
 
154
  */
 
155
  nsCOMPtr<imgIRequest> kungFuDeathGrip(this);
 
156
 
 
157
  mLoadGroup->RemoveRequest(this, NS_OK, nsnull);
 
158
  mIsInLoadGroup = PR_FALSE;
 
159
 
 
160
  // We're done with the loadgroup, release it.
 
161
  mLoadGroup = nsnull;
 
162
}
 
163
 
 
164
 
 
165
/**  nsIRequest / imgIRequest methods **/
 
166
 
 
167
/* readonly attribute wstring name; */
 
168
NS_IMETHODIMP imgRequestProxy::GetName(nsACString &aName)
 
169
{
 
170
  aName.Truncate();
 
171
  if (mOwner) {
 
172
    nsCOMPtr<nsIURI> uri;
 
173
    mOwner->GetURI(getter_AddRefs(uri));
 
174
    if (uri)
 
175
      uri->GetSpec(aName);
 
176
  }
 
177
  return NS_OK;
 
178
}
 
179
 
 
180
/* boolean isPending (); */
 
181
NS_IMETHODIMP imgRequestProxy::IsPending(PRBool *_retval)
 
182
{
 
183
    return NS_ERROR_NOT_IMPLEMENTED;
 
184
}
 
185
 
 
186
/* readonly attribute nsresult status; */
 
187
NS_IMETHODIMP imgRequestProxy::GetStatus(nsresult *aStatus)
 
188
{
 
189
    return NS_ERROR_NOT_IMPLEMENTED;
 
190
}
 
191
 
 
192
/* void cancel (in nsresult status); */
 
193
NS_IMETHODIMP imgRequestProxy::Cancel(nsresult status)
 
194
{
 
195
  if (mCanceled || !mOwner)
 
196
    return NS_ERROR_FAILURE;
 
197
 
 
198
  LOG_SCOPE(gImgLog, "imgRequestProxy::Cancel");
 
199
 
 
200
  PR_Lock(mLock);
 
201
 
 
202
  mCanceled = PR_TRUE;
 
203
  mListener = nsnull;
 
204
 
 
205
  PR_Unlock(mLock);
 
206
 
 
207
  mOwner->RemoveProxy(this, status, PR_FALSE);
 
208
 
 
209
  return NS_OK;
 
210
}
 
211
 
 
212
/* void suspend (); */
 
213
NS_IMETHODIMP imgRequestProxy::Suspend()
 
214
{
 
215
    return NS_ERROR_NOT_IMPLEMENTED;
 
216
}
 
217
 
 
218
/* void resume (); */
 
219
NS_IMETHODIMP imgRequestProxy::Resume()
 
220
{
 
221
    return NS_ERROR_NOT_IMPLEMENTED;
 
222
}
 
223
 
 
224
/* attribute nsILoadGroup loadGroup */
 
225
NS_IMETHODIMP imgRequestProxy::GetLoadGroup(nsILoadGroup **loadGroup)
 
226
{
 
227
  nsAutoLock lock(mLock);
 
228
  NS_IF_ADDREF(*loadGroup = mLoadGroup.get());
 
229
  return NS_OK;
 
230
}
 
231
NS_IMETHODIMP imgRequestProxy::SetLoadGroup(nsILoadGroup *loadGroup)
 
232
{
 
233
  nsAutoLock lock(mLock);
 
234
  mLoadGroup = loadGroup;
 
235
  return NS_OK;
 
236
}
 
237
 
 
238
/* attribute nsLoadFlags loadFlags */
 
239
NS_IMETHODIMP imgRequestProxy::GetLoadFlags(nsLoadFlags *flags)
 
240
{
 
241
  *flags = mLoadFlags;
 
242
  return NS_OK;
 
243
}
 
244
NS_IMETHODIMP imgRequestProxy::SetLoadFlags(nsLoadFlags flags)
 
245
{
 
246
  mLoadFlags = flags;
 
247
  return NS_OK;
 
248
}
 
249
 
 
250
/**  imgIRequest methods **/
 
251
 
 
252
/* attribute imgIContainer image; */
 
253
NS_IMETHODIMP imgRequestProxy::GetImage(imgIContainer * *aImage)
 
254
{
 
255
  if (!mOwner)
 
256
    return NS_ERROR_FAILURE;
 
257
 
 
258
  nsAutoLock lock(mLock);
 
259
  mOwner->GetImage(aImage);
 
260
  return NS_OK;
 
261
}
 
262
 
 
263
/* readonly attribute unsigned long imageStatus; */
 
264
NS_IMETHODIMP imgRequestProxy::GetImageStatus(PRUint32 *aStatus)
 
265
{
 
266
  if (!mOwner) {
 
267
    *aStatus = imgIRequest::STATUS_ERROR;
 
268
    return NS_ERROR_FAILURE;
 
269
  }
 
270
 
 
271
  nsAutoLock lock(mLock);
 
272
  *aStatus = mOwner->GetImageStatus();
 
273
  return NS_OK;
 
274
}
 
275
 
 
276
/* readonly attribute nsIURI URI; */
 
277
NS_IMETHODIMP imgRequestProxy::GetURI(nsIURI **aURI)
 
278
{
 
279
  if (!mOwner)
 
280
    return NS_ERROR_FAILURE;
 
281
 
 
282
  nsAutoLock lock(mLock);
 
283
  return mOwner->GetURI(aURI);
 
284
}
 
285
 
 
286
/* readonly attribute imgIDecoderObserver decoderObserver; */
 
287
NS_IMETHODIMP imgRequestProxy::GetDecoderObserver(imgIDecoderObserver **aDecoderObserver)
 
288
{
 
289
  *aDecoderObserver = mListener;
 
290
  NS_IF_ADDREF(*aDecoderObserver);
 
291
  return NS_OK;
 
292
}
 
293
 
 
294
/* readonly attribute string mimeType; */
 
295
NS_IMETHODIMP imgRequestProxy::GetMimeType(char **aMimeType)
 
296
{
 
297
  if (!mOwner)
 
298
    return NS_ERROR_FAILURE;
 
299
 
 
300
  const char *type = mOwner->GetMimeType();
 
301
  if (!type)
 
302
    return NS_ERROR_FAILURE;
 
303
 
 
304
  *aMimeType = nsCRT::strdup(type);
 
305
 
 
306
  return NS_OK;
 
307
}
 
308
 
 
309
NS_IMETHODIMP imgRequestProxy::Clone(imgIDecoderObserver* aObserver,
 
310
                                     imgIRequest** aClone)
 
311
{
 
312
  NS_PRECONDITION(aClone, "Null out param");
 
313
  *aClone = nsnull;
 
314
  imgRequestProxy* clone = new imgRequestProxy();
 
315
  if (!clone) {
 
316
    return NS_ERROR_OUT_OF_MEMORY;
 
317
  }
 
318
  NS_ADDREF(clone);
 
319
 
 
320
  // It is important to call |SetLoadFlags()| before calling |Init()| because
 
321
  // |Init()| adds the request to the loadgroup.
 
322
  clone->SetLoadFlags(mLoadFlags);
 
323
  nsresult rv = clone->Init(mOwner, mLoadGroup, aObserver);
 
324
  if (NS_FAILED(rv)) {
 
325
    NS_RELEASE(clone);
 
326
    return rv;
 
327
  }
 
328
 
 
329
  // Send the notifications to the clone's observer
 
330
  mOwner->NotifyProxyListener(clone);
 
331
 
 
332
  *aClone = clone;
 
333
  return NS_OK;
 
334
}
 
335
 
 
336
/** imgIContainerObserver methods **/
 
337
 
 
338
void imgRequestProxy::FrameChanged(imgIContainer *container, gfxIImageFrame *newframe, nsRect * dirtyRect)
 
339
{
 
340
  LOG_FUNC(gImgLog, "imgRequestProxy::FrameChanged");
 
341
 
 
342
  if (mListener) {
 
343
    // Hold a ref to the listener while we call it, just in case.
 
344
    nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
 
345
    mListener->FrameChanged(container, newframe, dirtyRect);
 
346
  }
 
347
}
 
348
 
 
349
/** imgIDecoderObserver methods **/
 
350
 
 
351
void imgRequestProxy::OnStartDecode()
 
352
{
 
353
  LOG_FUNC(gImgLog, "imgRequestProxy::OnStartDecode");
 
354
 
 
355
  if (mListener) {
 
356
    // Hold a ref to the listener while we call it, just in case.
 
357
    nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
 
358
    mListener->OnStartDecode(this);
 
359
  }
 
360
}
 
361
 
 
362
void imgRequestProxy::OnStartContainer(imgIContainer *image)
 
363
{
 
364
  LOG_FUNC(gImgLog, "imgRequestProxy::OnStartContainer");
 
365
 
 
366
  if (mListener) {
 
367
    // Hold a ref to the listener while we call it, just in case.
 
368
    nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
 
369
    mListener->OnStartContainer(this, image);
 
370
  }
 
371
}
 
372
 
 
373
void imgRequestProxy::OnStartFrame(gfxIImageFrame *frame)
 
374
{
 
375
  LOG_FUNC(gImgLog, "imgRequestProxy::OnStartFrame");
 
376
 
 
377
  if (mListener) {
 
378
    // Hold a ref to the listener while we call it, just in case.
 
379
    nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
 
380
    mListener->OnStartFrame(this, frame);
 
381
  }
 
382
}
 
383
 
 
384
void imgRequestProxy::OnDataAvailable(gfxIImageFrame *frame, const nsRect * rect)
 
385
{
 
386
  LOG_FUNC(gImgLog, "imgRequestProxy::OnDataAvailable");
 
387
 
 
388
  if (mListener) {
 
389
    // Hold a ref to the listener while we call it, just in case.
 
390
    nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
 
391
    mListener->OnDataAvailable(this, frame, rect);
 
392
  }
 
393
}
 
394
 
 
395
void imgRequestProxy::OnStopFrame(gfxIImageFrame *frame)
 
396
{
 
397
  LOG_FUNC(gImgLog, "imgRequestProxy::OnStopFrame");
 
398
 
 
399
  if (mListener) {
 
400
    // Hold a ref to the listener while we call it, just in case.
 
401
    nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
 
402
    mListener->OnStopFrame(this, frame);
 
403
  }
 
404
}
 
405
 
 
406
void imgRequestProxy::OnStopContainer(imgIContainer *image)
 
407
{
 
408
  LOG_FUNC(gImgLog, "imgRequestProxy::OnStopContainer");
 
409
 
 
410
  if (mListener) {
 
411
    // Hold a ref to the listener while we call it, just in case.
 
412
    nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
 
413
    mListener->OnStopContainer(this, image);
 
414
  }
 
415
}
 
416
 
 
417
void imgRequestProxy::OnStopDecode(nsresult status, const PRUnichar *statusArg)
 
418
{
 
419
  LOG_FUNC(gImgLog, "imgRequestProxy::OnStopDecode");
 
420
 
 
421
  if (mListener) {
 
422
    // Hold a ref to the listener while we call it, just in case.
 
423
    nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
 
424
    mListener->OnStopDecode(this, status, statusArg);
 
425
  }
 
426
}
 
427
 
 
428
 
 
429
 
 
430
void imgRequestProxy::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
 
431
{
 
432
#ifdef PR_LOGGING
 
433
  nsCAutoString name;
 
434
  GetName(name);
 
435
  LOG_FUNC_WITH_PARAM(gImgLog, "imgRequestProxy::OnStartRequest", "name", name.get());
 
436
#endif
 
437
}
 
438
 
 
439
void imgRequestProxy::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult statusCode)
 
440
{
 
441
#ifdef PR_LOGGING
 
442
  nsCAutoString name;
 
443
  GetName(name);
 
444
  LOG_FUNC_WITH_PARAM(gImgLog, "imgRequestProxy::OnStopRequest", "name", name.get());
 
445
#endif
 
446
 
 
447
  RemoveFromLoadGroup();
 
448
}
 
449