1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/plugins/ipc/BrowserStreamParent.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,157 @@ 1.4 +/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */ 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 + 1.10 +#include "BrowserStreamParent.h" 1.11 +#include "PluginInstanceParent.h" 1.12 +#include "nsNPAPIPlugin.h" 1.13 + 1.14 +#include "mozilla/unused.h" 1.15 + 1.16 +// How much data are we willing to send across the wire 1.17 +// in one chunk? 1.18 +static const int32_t kSendDataChunk = 0x4000; 1.19 + 1.20 +namespace mozilla { 1.21 +namespace plugins { 1.22 + 1.23 +BrowserStreamParent::BrowserStreamParent(PluginInstanceParent* npp, 1.24 + NPStream* stream) 1.25 + : mNPP(npp) 1.26 + , mStream(stream) 1.27 + , mState(ALIVE) 1.28 +{ 1.29 + mStream->pdata = static_cast<AStream*>(this); 1.30 +} 1.31 + 1.32 +BrowserStreamParent::~BrowserStreamParent() 1.33 +{ 1.34 +} 1.35 + 1.36 +bool 1.37 +BrowserStreamParent::AnswerNPN_RequestRead(const IPCByteRanges& ranges, 1.38 + NPError* result) 1.39 +{ 1.40 + PLUGIN_LOG_DEBUG_FUNCTION; 1.41 + 1.42 + switch (mState) { 1.43 + case ALIVE: 1.44 + break; 1.45 + 1.46 + case DYING: 1.47 + *result = NPERR_GENERIC_ERROR; 1.48 + return true; 1.49 + 1.50 + default: 1.51 + NS_ERROR("Unexpected state"); 1.52 + return false; 1.53 + } 1.54 + 1.55 + if (!mStream) 1.56 + return false; 1.57 + 1.58 + if (ranges.size() > INT32_MAX) 1.59 + return false; 1.60 + 1.61 + nsAutoArrayPtr<NPByteRange> rp(new NPByteRange[ranges.size()]); 1.62 + for (uint32_t i = 0; i < ranges.size(); ++i) { 1.63 + rp[i].offset = ranges[i].offset; 1.64 + rp[i].length = ranges[i].length; 1.65 + rp[i].next = &rp[i + 1]; 1.66 + } 1.67 + rp[ranges.size() - 1].next = nullptr; 1.68 + 1.69 + *result = mNPP->mNPNIface->requestread(mStream, rp); 1.70 + return true; 1.71 +} 1.72 + 1.73 +bool 1.74 +BrowserStreamParent::RecvNPN_DestroyStream(const NPReason& reason) 1.75 +{ 1.76 + switch (mState) { 1.77 + case ALIVE: 1.78 + break; 1.79 + 1.80 + case DYING: 1.81 + return true; 1.82 + 1.83 + default: 1.84 + NS_ERROR("Unexpected state"); 1.85 + return false; 1.86 + }; 1.87 + 1.88 + mNPP->mNPNIface->destroystream(mNPP->mNPP, mStream, reason); 1.89 + return true; 1.90 +} 1.91 + 1.92 +void 1.93 +BrowserStreamParent::NPP_DestroyStream(NPReason reason) 1.94 +{ 1.95 + NS_ASSERTION(ALIVE == mState, "NPP_DestroyStream called twice?"); 1.96 + mState = DYING; 1.97 + unused << SendNPP_DestroyStream(reason); 1.98 +} 1.99 + 1.100 +bool 1.101 +BrowserStreamParent::RecvStreamDestroyed() 1.102 +{ 1.103 + if (DYING != mState) { 1.104 + NS_ERROR("Unexpected state"); 1.105 + return false; 1.106 + } 1.107 + 1.108 + mStreamPeer = nullptr; 1.109 + 1.110 + mState = DELETING; 1.111 + return Send__delete__(this); 1.112 +} 1.113 + 1.114 +int32_t 1.115 +BrowserStreamParent::WriteReady() 1.116 +{ 1.117 + return kSendDataChunk; 1.118 +} 1.119 + 1.120 +int32_t 1.121 +BrowserStreamParent::Write(int32_t offset, 1.122 + int32_t len, 1.123 + void* buffer) 1.124 +{ 1.125 + PLUGIN_LOG_DEBUG_FUNCTION; 1.126 + 1.127 + NS_ASSERTION(ALIVE == mState, "Sending data after NPP_DestroyStream?"); 1.128 + NS_ASSERTION(len > 0, "Non-positive length to NPP_Write"); 1.129 + 1.130 + if (len > kSendDataChunk) 1.131 + len = kSendDataChunk; 1.132 + 1.133 + return SendWrite(offset, 1.134 + nsCString(static_cast<char*>(buffer), len), 1.135 + mStream->end) ? 1.136 + len : -1; 1.137 +} 1.138 + 1.139 +void 1.140 +BrowserStreamParent::StreamAsFile(const char* fname) 1.141 +{ 1.142 + PLUGIN_LOG_DEBUG_FUNCTION; 1.143 + 1.144 + NS_ASSERTION(ALIVE == mState, 1.145 + "Calling streamasfile after NPP_DestroyStream?"); 1.146 + 1.147 + // Make sure our stream survives until the plugin process tells us we've 1.148 + // been destroyed (until RecvStreamDestroyed() is called). Since we retain 1.149 + // mStreamPeer at most once, we won't get in trouble if StreamAsFile() is 1.150 + // called more than once. 1.151 + if (!mStreamPeer) { 1.152 + nsNPAPIPlugin::RetainStream(mStream, getter_AddRefs(mStreamPeer)); 1.153 + } 1.154 + 1.155 + unused << SendNPP_StreamAsFile(nsCString(fname)); 1.156 + return; 1.157 +} 1.158 + 1.159 +} // namespace plugins 1.160 +} // namespace mozilla