1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/base/src/nsBaseContentStream.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,137 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "nsBaseContentStream.h" 1.10 +#include "nsStreamUtils.h" 1.11 + 1.12 +//----------------------------------------------------------------------------- 1.13 + 1.14 +void 1.15 +nsBaseContentStream::DispatchCallback(bool async) 1.16 +{ 1.17 + if (!mCallback) 1.18 + return; 1.19 + 1.20 + // It's important to clear mCallback and mCallbackTarget up-front because the 1.21 + // OnInputStreamReady implementation may call our AsyncWait method. 1.22 + 1.23 + nsCOMPtr<nsIInputStreamCallback> callback; 1.24 + if (async) { 1.25 + callback = NS_NewInputStreamReadyEvent(mCallback, mCallbackTarget); 1.26 + mCallback = nullptr; 1.27 + } else { 1.28 + callback.swap(mCallback); 1.29 + } 1.30 + mCallbackTarget = nullptr; 1.31 + 1.32 + callback->OnInputStreamReady(this); 1.33 +} 1.34 + 1.35 +//----------------------------------------------------------------------------- 1.36 +// nsBaseContentStream::nsISupports 1.37 + 1.38 +NS_IMPL_ADDREF(nsBaseContentStream) 1.39 +NS_IMPL_RELEASE(nsBaseContentStream) 1.40 + 1.41 +// We only support nsIAsyncInputStream when we are in non-blocking mode. 1.42 +NS_INTERFACE_MAP_BEGIN(nsBaseContentStream) 1.43 + NS_INTERFACE_MAP_ENTRY(nsIInputStream) 1.44 + NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAsyncInputStream, mNonBlocking) 1.45 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInputStream) 1.46 +NS_INTERFACE_MAP_END_THREADSAFE 1.47 + 1.48 +//----------------------------------------------------------------------------- 1.49 +// nsBaseContentStream::nsIInputStream 1.50 + 1.51 +NS_IMETHODIMP 1.52 +nsBaseContentStream::Close() 1.53 +{ 1.54 + return IsClosed() ? NS_OK : CloseWithStatus(NS_BASE_STREAM_CLOSED); 1.55 +} 1.56 + 1.57 +NS_IMETHODIMP 1.58 +nsBaseContentStream::Available(uint64_t *result) 1.59 +{ 1.60 + *result = 0; 1.61 + return mStatus; 1.62 +} 1.63 + 1.64 +NS_IMETHODIMP 1.65 +nsBaseContentStream::Read(char *buf, uint32_t count, uint32_t *result) 1.66 +{ 1.67 + return ReadSegments(NS_CopySegmentToBuffer, buf, count, result); 1.68 +} 1.69 + 1.70 +NS_IMETHODIMP 1.71 +nsBaseContentStream::ReadSegments(nsWriteSegmentFun fun, void *closure, 1.72 + uint32_t count, uint32_t *result) 1.73 +{ 1.74 + *result = 0; 1.75 + 1.76 + if (mStatus == NS_BASE_STREAM_CLOSED) 1.77 + return NS_OK; 1.78 + 1.79 + // No data yet 1.80 + if (!IsClosed() && IsNonBlocking()) 1.81 + return NS_BASE_STREAM_WOULD_BLOCK; 1.82 + 1.83 + return mStatus; 1.84 +} 1.85 + 1.86 +NS_IMETHODIMP 1.87 +nsBaseContentStream::IsNonBlocking(bool *result) 1.88 +{ 1.89 + *result = mNonBlocking; 1.90 + return NS_OK; 1.91 +} 1.92 + 1.93 +//----------------------------------------------------------------------------- 1.94 +// nsBaseContentStream::nsIAsyncInputStream 1.95 + 1.96 +NS_IMETHODIMP 1.97 +nsBaseContentStream::CloseWithStatus(nsresult status) 1.98 +{ 1.99 + if (IsClosed()) 1.100 + return NS_OK; 1.101 + 1.102 + NS_ENSURE_ARG(NS_FAILED(status)); 1.103 + mStatus = status; 1.104 + 1.105 + DispatchCallback(); 1.106 + return NS_OK; 1.107 +} 1.108 + 1.109 +NS_IMETHODIMP 1.110 +nsBaseContentStream::AsyncWait(nsIInputStreamCallback *callback, 1.111 + uint32_t flags, uint32_t requestedCount, 1.112 + nsIEventTarget *target) 1.113 +{ 1.114 + // Our _only_ consumer is nsInputStreamPump, so we simplify things here by 1.115 + // making assumptions about how we will be called. 1.116 + NS_ASSERTION(target, "unexpected parameter"); 1.117 + NS_ASSERTION(flags == 0, "unexpected parameter"); 1.118 + NS_ASSERTION(requestedCount == 0, "unexpected parameter"); 1.119 + 1.120 +#ifdef DEBUG 1.121 + bool correctThread; 1.122 + target->IsOnCurrentThread(&correctThread); 1.123 + NS_ASSERTION(correctThread, "event target must be on the current thread"); 1.124 +#endif 1.125 + 1.126 + mCallback = callback; 1.127 + mCallbackTarget = target; 1.128 + 1.129 + if (!mCallback) 1.130 + return NS_OK; 1.131 + 1.132 + // If we're already closed, then dispatch this callback immediately. 1.133 + if (IsClosed()) { 1.134 + DispatchCallback(); 1.135 + return NS_OK; 1.136 + } 1.137 + 1.138 + OnCallbackPending(); 1.139 + return NS_OK; 1.140 +}