Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / netwerk / base / src / nsBaseContentStream.cpp
blob20b4ce3b985e1efcfe53f1fd40538ab501c9759d
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is Google Inc.
18 * Portions created by the Initial Developer are Copyright (C) 2005
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
22 * Darin Fisher <darin@meer.net>
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include "nsBaseContentStream.h"
39 #include "nsStreamUtils.h"
41 //-----------------------------------------------------------------------------
43 void
44 nsBaseContentStream::DispatchCallback(PRBool async)
46 if (!mCallback)
47 return;
49 // It's important to clear mCallback and mCallbackTarget up-front because the
50 // OnInputStreamReady implementation may call our AsyncWait method.
52 nsCOMPtr<nsIInputStreamCallback> callback;
53 if (async) {
54 NS_NewInputStreamReadyEvent(getter_AddRefs(callback), mCallback,
55 mCallbackTarget);
56 if (!callback)
57 return; // out of memory!
58 mCallback = nsnull;
59 } else {
60 callback.swap(mCallback);
62 mCallbackTarget = nsnull;
64 callback->OnInputStreamReady(this);
67 //-----------------------------------------------------------------------------
68 // nsBaseContentStream::nsISupports
70 NS_IMPL_THREADSAFE_ADDREF(nsBaseContentStream)
71 NS_IMPL_THREADSAFE_RELEASE(nsBaseContentStream)
73 // We only support nsIAsyncInputStream when we are in non-blocking mode.
74 NS_INTERFACE_MAP_BEGIN(nsBaseContentStream)
75 NS_INTERFACE_MAP_ENTRY(nsIInputStream)
76 NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAsyncInputStream, mNonBlocking)
77 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInputStream)
78 NS_INTERFACE_MAP_END_THREADSAFE
80 //-----------------------------------------------------------------------------
81 // nsBaseContentStream::nsIInputStream
83 NS_IMETHODIMP
84 nsBaseContentStream::Close()
86 return IsClosed() ? NS_OK : CloseWithStatus(NS_BASE_STREAM_CLOSED);
89 NS_IMETHODIMP
90 nsBaseContentStream::Available(PRUint32 *result)
92 *result = 0;
93 return mStatus;
96 NS_IMETHODIMP
97 nsBaseContentStream::Read(char *buf, PRUint32 count, PRUint32 *result)
99 return ReadSegments(NS_CopySegmentToBuffer, buf, count, result);
102 NS_IMETHODIMP
103 nsBaseContentStream::ReadSegments(nsWriteSegmentFun fun, void *closure,
104 PRUint32 count, PRUint32 *result)
106 *result = 0;
108 if (mStatus == NS_BASE_STREAM_CLOSED)
109 return NS_OK;
111 // No data yet
112 if (!IsClosed() && IsNonBlocking())
113 return NS_BASE_STREAM_WOULD_BLOCK;
115 return mStatus;
118 NS_IMETHODIMP
119 nsBaseContentStream::IsNonBlocking(PRBool *result)
121 *result = mNonBlocking;
122 return NS_OK;
125 //-----------------------------------------------------------------------------
126 // nsBaseContentStream::nsIAsyncInputStream
128 NS_IMETHODIMP
129 nsBaseContentStream::CloseWithStatus(nsresult status)
131 if (IsClosed())
132 return NS_OK;
134 NS_ENSURE_ARG(NS_FAILED(status));
135 mStatus = status;
137 DispatchCallback();
138 return NS_OK;
141 NS_IMETHODIMP
142 nsBaseContentStream::AsyncWait(nsIInputStreamCallback *callback,
143 PRUint32 flags, PRUint32 requestedCount,
144 nsIEventTarget *target)
146 // Our _only_ consumer is nsInputStreamPump, so we simplify things here by
147 // making assumptions about how we will be called.
148 NS_ASSERTION(target, "unexpected parameter");
149 NS_ASSERTION(flags == 0, "unexpected parameter");
150 NS_ASSERTION(requestedCount == 0, "unexpected parameter");
152 #ifdef DEBUG
153 PRBool correctThread;
154 target->IsOnCurrentThread(&correctThread);
155 NS_ASSERTION(correctThread, "event target must be on the current thread");
156 #endif
158 mCallback = callback;
159 mCallbackTarget = target;
161 if (!mCallback)
162 return NS_OK;
164 // If we're already closed, then dispatch this callback immediately.
165 if (IsClosed()) {
166 DispatchCallback();
167 return NS_OK;
170 OnCallbackPending();
171 return NS_OK;