mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-11 08:13:35 +00:00
Fixed up input stream buffering. Fixed some refcounting problems.
This commit is contained in:
parent
f44e8829c5
commit
c4eaaf4ebe
@ -511,14 +511,21 @@ NS_IMPL_RELEASE(SimplePlugin);
|
||||
* resources allocated by NPP_Initialize.
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
|
||||
SimplePlugin* gPlugin = NULL;
|
||||
|
||||
extern "C" NS_EXPORT nsresult
|
||||
NSGetFactory(const nsCID &aClass, nsIFactory **aFactory)
|
||||
{
|
||||
if (aClass.Equals(kIPluginIID)) {
|
||||
if (gPlugin) {
|
||||
*aFactory = gPlugin;
|
||||
return NS_OK;
|
||||
}
|
||||
SimplePlugin* fact = new SimplePlugin();
|
||||
if (fact == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
fact->AddRef();
|
||||
gPlugin = fact;
|
||||
*aFactory = fact;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -708,6 +715,25 @@ SimplePluginInstance::Start(void)
|
||||
sprintf(factString, "my favorite function returned %d\n", v);
|
||||
DisplayJavaMessage(factString, -1);
|
||||
}
|
||||
|
||||
#ifdef NEW_PLUGIN_STREAM_API
|
||||
// Try getting some streams:
|
||||
gPlugin->GetPluginManager()->GetURL(this, "http://warp", NULL,
|
||||
new SimplePluginStreamListener(this));
|
||||
|
||||
gPlugin->GetPluginManager()->GetURL(this, "http://home.netscape.com", NULL,
|
||||
new SimplePluginStreamListener(this),
|
||||
nsPluginStreamType_AsFile);
|
||||
|
||||
gPlugin->GetPluginManager()->GetURL(this, "http://warp/java", NULL,
|
||||
new SimplePluginStreamListener(this),
|
||||
nsPluginStreamType_AsFileOnly);
|
||||
|
||||
gPlugin->GetPluginManager()->GetURL(this, "http://warp/java/oji", NULL,
|
||||
new SimplePluginStreamListener(this),
|
||||
nsPluginStreamType_Seek);
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1080,6 +1106,11 @@ native_Simple_printToStdout(JRIEnv* env, struct Simple* self,
|
||||
void
|
||||
SimplePluginInstance::DisplayJavaMessage(char* msg, int len)
|
||||
{
|
||||
#ifdef XP_PC
|
||||
OutputDebugString(msg);
|
||||
OutputDebugString("\n");
|
||||
#endif
|
||||
|
||||
Simple* javaPeer; // instance of the java class (there's no package qualifier)
|
||||
java_lang_String* str;
|
||||
|
||||
|
@ -181,6 +181,7 @@ np_processURLNode(np_urlsnode* node, np_instance* instance, int status)
|
||||
nsIPluginStreamListener* listener = inStr->GetListener();
|
||||
nsresult err = listener->OnStopBinding(node->urls->address,
|
||||
(nsPluginReason)np_statusToReason(status));
|
||||
inStr->Release();
|
||||
// XXX ignore error?
|
||||
|
||||
#else // !NEW_PLUGIN_STREAM_API
|
||||
@ -580,10 +581,12 @@ NPL_Write(NET_StreamClass *stream, const unsigned char *str, int32 len)
|
||||
if (newstream->handle->userPlugin) {
|
||||
#ifdef NEW_PLUGIN_STREAM_API
|
||||
|
||||
nsPluginInputStream* instr = (nsPluginInputStream*)newstream->pstream->pdata;
|
||||
nsIPluginStreamListener* listener = instr->GetListener();
|
||||
instr->SetReadBuffer(len, (const char*)str);
|
||||
nsresult err = listener->OnDataAvailable((const char*)urls->address, instr, urls->position, len);
|
||||
nsPluginInputStream* inStr = (nsPluginInputStream*)newstream->pstream->pdata;
|
||||
nsIPluginStreamListener* listener = inStr->GetListener();
|
||||
nsresult err = inStr->ReceiveData((const char*)str, urls->position, len);
|
||||
if (err == NS_OK) {
|
||||
err = listener->OnDataAvailable((const char*)urls->address, inStr, urls->position, len);
|
||||
}
|
||||
PR_ASSERT(err == NS_OK); // XXX this error should go somewhere
|
||||
|
||||
#else // !NEW_PLUGIN_STREAM_API
|
||||
@ -803,8 +806,10 @@ np_destroystream(np_stream *stream, NPError reason)
|
||||
TRACEMSG(("npglue.c: CallNPP_DestroyStreamProc"));
|
||||
if (stream->handle->userPlugin) {
|
||||
#ifdef NEW_PLUGIN_STREAM_API
|
||||
#if 0 // released in np_processURLNode during NPL_URLExit
|
||||
nsPluginInputStream* inStr = (nsPluginInputStream*)stream->pstream->pdata;
|
||||
inStr->Release();
|
||||
#endif
|
||||
#else // !NEW_PLUGIN_STREAM_API
|
||||
nsPluginStreamPeer* peerStream = (nsPluginStreamPeer*)stream->pstream->pdata;
|
||||
nsIPluginStream* userStream = peerStream->GetUserStream();
|
||||
@ -958,13 +963,13 @@ NPL_Abort(NET_StreamClass *stream, int status)
|
||||
|
||||
newstream->nstream = NULL; /* Remove reference to netlib stream */
|
||||
|
||||
/*
|
||||
* MK_UNABLE_TO_CONVERT is the special status code we
|
||||
* return from NPL_Write to cancel the original netlib
|
||||
* stream when we get a byte-range request, so we don't
|
||||
* want to destroy the plug-in stream in this case (we
|
||||
* shouldn't get this status code any other time here).
|
||||
*/
|
||||
/*
|
||||
* MK_UNABLE_TO_CONVERT is the special status code we
|
||||
* return from NPL_Write to cancel the original netlib
|
||||
* stream when we get a byte-range request, so we don't
|
||||
* want to destroy the plug-in stream in this case (we
|
||||
* shouldn't get this status code any other time here).
|
||||
*/
|
||||
if (!newstream->dontclose || (status < 0 && status != MK_UNABLE_TO_CONVERT))
|
||||
np_destroystream(newstream, np_statusToReason(status));
|
||||
}
|
||||
|
@ -780,20 +780,27 @@ public:
|
||||
mStream = stream;
|
||||
}
|
||||
|
||||
void SetReadBuffer(PRUint32 len, const char* buffer) {
|
||||
mBuffer = PL_strdup(buffer);
|
||||
mBufferLength = len;
|
||||
mAmountRead = 0;
|
||||
}
|
||||
nsresult ReceiveData(const char* buffer, PRUint32 offset, PRUint32 len);
|
||||
void Cleanup(void);
|
||||
|
||||
protected:
|
||||
nsIPluginStreamListener* mListener;
|
||||
nsPluginStreamType mStreamType;
|
||||
URL_Struct* mUrls;
|
||||
np_stream* mStream;
|
||||
char* mBuffer;
|
||||
PRUint32 mBufferLength;
|
||||
PRUint32 mAmountRead;
|
||||
|
||||
struct BufferElement {
|
||||
BufferElement* next;
|
||||
char* segment;
|
||||
PRUint32 offset;
|
||||
PRUint32 length;
|
||||
};
|
||||
|
||||
BufferElement* mBuffer;
|
||||
// PRUint32 mReadCursor;
|
||||
|
||||
// PRUint32 mBufferLength;
|
||||
// PRUint32 mAmountRead;
|
||||
|
||||
};
|
||||
|
||||
|
@ -159,8 +159,7 @@ nsPluginManager::Create(nsISupports* outer, const nsIID& aIID, void* *aInstanceP
|
||||
if (mgr == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
mgr->AddRef();
|
||||
*aInstancePtr = mgr->GetInner();
|
||||
*aInstancePtr = (outer != NULL)? (void *)mgr->GetInner(): (void *)mgr;
|
||||
*aInstancePtr = outer ? (void *)mgr->GetInner() : (void *)mgr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -613,6 +612,15 @@ nsPluginManager::GetURL(nsISupports* pluginInst,
|
||||
const char* referrer,
|
||||
PRBool forceJSEnabled)
|
||||
{
|
||||
void* notifyData = NULL;
|
||||
if (listener) {
|
||||
nsPluginInputStream* inStr = new nsPluginInputStream(listener, streamType);
|
||||
if (inStr == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
inStr->AddRef();
|
||||
notifyData = inStr;
|
||||
}
|
||||
|
||||
NPError rslt = NPERR_INVALID_PARAM;
|
||||
nsIPluginInstance* inst = NULL;
|
||||
if (pluginInst->QueryInterface(kIPluginInstanceIID, (void**)&inst) == NS_OK) {
|
||||
@ -620,12 +628,6 @@ nsPluginManager::GetURL(nsISupports* pluginInst,
|
||||
nsPluginInstancePeer* peer;
|
||||
nsresult err = inst->GetPeer((nsIPluginInstancePeer**)&peer);
|
||||
if (err == NS_OK) {
|
||||
void* notifyData = NULL;
|
||||
if (listener) {
|
||||
nsPluginInputStream* inStr = new nsPluginInputStream(listener, streamType);
|
||||
notifyData = inStr;
|
||||
}
|
||||
|
||||
if (PR_CurrentThread() == mozilla_thread) {
|
||||
NPP npp = peer->GetNPP();
|
||||
rslt = np_geturlinternal(npp,
|
||||
@ -720,6 +722,15 @@ nsPluginManager::PostURL(nsISupports* pluginInst,
|
||||
PRUint32 postHeadersLen,
|
||||
const char* postHeaders)
|
||||
{
|
||||
void* notifyData = NULL;
|
||||
if (listener) {
|
||||
nsPluginInputStream* inStr = new nsPluginInputStream(listener, streamType);
|
||||
if (inStr == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
inStr->AddRef();
|
||||
notifyData = inStr;
|
||||
}
|
||||
|
||||
NPError rslt = NPERR_INVALID_PARAM;
|
||||
nsIPluginInstance* inst = NULL;
|
||||
if (pluginInst->QueryInterface(kIPluginInstanceIID, (void**)&inst) == NS_OK) {
|
||||
@ -727,12 +738,6 @@ nsPluginManager::PostURL(nsISupports* pluginInst,
|
||||
nsPluginInstancePeer* peer;
|
||||
nsresult err = inst->GetPeer((nsIPluginInstancePeer**)&peer);
|
||||
if (err == NS_OK) {
|
||||
void* notifyData = NULL;
|
||||
if (listener) {
|
||||
nsPluginInputStream* inStr = new nsPluginInputStream(listener, streamType);
|
||||
notifyData = inStr;
|
||||
}
|
||||
|
||||
if (PR_CurrentThread() == mozilla_thread) {
|
||||
NPP npp = peer->GetNPP();
|
||||
PR_ASSERT(postHeaders == NULL); // XXX need to deal with postHeaders
|
||||
@ -1628,7 +1633,8 @@ nsPluginInputStream::nsPluginInputStream(nsIPluginStreamListener* listener,
|
||||
nsPluginStreamType streamType)
|
||||
: mListener(listener), mStreamType(streamType),
|
||||
mUrls(NULL), mStream(NULL),
|
||||
mBuffer(NULL), mBufferLength(0), mAmountRead(0)
|
||||
mBuffer(NULL)
|
||||
// mBuffer(NULL), mBufferLength(0), mAmountRead(0)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
listener->AddRef();
|
||||
@ -1636,8 +1642,8 @@ nsPluginInputStream::nsPluginInputStream(nsIPluginStreamListener* listener,
|
||||
|
||||
nsPluginInputStream::~nsPluginInputStream(void)
|
||||
{
|
||||
Cleanup();
|
||||
mListener->Release();
|
||||
PL_strfree(mBuffer);
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsPluginInputStream);
|
||||
@ -1659,9 +1665,26 @@ nsPluginInputStream::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
void
|
||||
nsPluginInputStream::Cleanup(void)
|
||||
{
|
||||
if (mBuffer) {
|
||||
// free the buffered data
|
||||
BufferElement* element = mBuffer;
|
||||
while (element != NULL) {
|
||||
BufferElement* next = element->next;
|
||||
PL_strfree(element->segment);
|
||||
delete element;
|
||||
element = next;
|
||||
}
|
||||
mBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsPluginInputStream::Close(void)
|
||||
{
|
||||
Cleanup();
|
||||
NPError err = npn_destroystream(mStream->instance->npp, mStream->pstream,
|
||||
nsPluginReason_UserBreak);
|
||||
return fromNPError[err];
|
||||
@ -1678,17 +1701,40 @@ nsPluginInputStream::GetLength(PRInt32 *aLength)
|
||||
#endif
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPluginInputStream::ReceiveData(const char* buffer, PRUint32 offset, PRUint32 len)
|
||||
{
|
||||
BufferElement* element = new BufferElement;
|
||||
if (element == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
element->segment = PL_strdup(buffer);
|
||||
element->offset = offset;
|
||||
element->length = len;
|
||||
element->next = mBuffer;
|
||||
mBuffer = element;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsPluginInputStream::Read(char* aBuf, PRInt32 aOffset, PRInt32 aCount,
|
||||
PRInt32 *aReadCount)
|
||||
{
|
||||
if (aOffset > (PRInt32)mBufferLength)
|
||||
return NS_ERROR_FAILURE; // XXX right error?
|
||||
PRUint32 cnt = PR_MIN(aCount, (PRInt32)mBufferLength - aOffset);
|
||||
memcpy(aBuf, &mBuffer[aOffset], cnt);
|
||||
*aReadCount = cnt;
|
||||
mAmountRead -= cnt;
|
||||
return NS_OK;
|
||||
BufferElement* element;
|
||||
for (element = mBuffer; element != NULL; element = element->next) {
|
||||
if ((PRInt32)element->offset <= aOffset
|
||||
&& aOffset < (PRInt32)(element->offset + element->length)) {
|
||||
// found our segment
|
||||
PRUint32 segmentIndex = aOffset - element->offset;
|
||||
PRUint32 segmentAmount = element->length - segmentIndex;
|
||||
if (aCount > (PRInt32)segmentAmount) {
|
||||
return NS_BASE_STREAM_EOF; // XXX right error?
|
||||
}
|
||||
memcpy(aBuf, &element->segment[segmentIndex], aCount);
|
||||
// mReadCursor = segmentIndex + aCount;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
|
@ -511,14 +511,21 @@ NS_IMPL_RELEASE(SimplePlugin);
|
||||
* resources allocated by NPP_Initialize.
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
|
||||
SimplePlugin* gPlugin = NULL;
|
||||
|
||||
extern "C" NS_EXPORT nsresult
|
||||
NSGetFactory(const nsCID &aClass, nsIFactory **aFactory)
|
||||
{
|
||||
if (aClass.Equals(kIPluginIID)) {
|
||||
if (gPlugin) {
|
||||
*aFactory = gPlugin;
|
||||
return NS_OK;
|
||||
}
|
||||
SimplePlugin* fact = new SimplePlugin();
|
||||
if (fact == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
fact->AddRef();
|
||||
gPlugin = fact;
|
||||
*aFactory = fact;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -708,6 +715,25 @@ SimplePluginInstance::Start(void)
|
||||
sprintf(factString, "my favorite function returned %d\n", v);
|
||||
DisplayJavaMessage(factString, -1);
|
||||
}
|
||||
|
||||
#ifdef NEW_PLUGIN_STREAM_API
|
||||
// Try getting some streams:
|
||||
gPlugin->GetPluginManager()->GetURL(this, "http://warp", NULL,
|
||||
new SimplePluginStreamListener(this));
|
||||
|
||||
gPlugin->GetPluginManager()->GetURL(this, "http://home.netscape.com", NULL,
|
||||
new SimplePluginStreamListener(this),
|
||||
nsPluginStreamType_AsFile);
|
||||
|
||||
gPlugin->GetPluginManager()->GetURL(this, "http://warp/java", NULL,
|
||||
new SimplePluginStreamListener(this),
|
||||
nsPluginStreamType_AsFileOnly);
|
||||
|
||||
gPlugin->GetPluginManager()->GetURL(this, "http://warp/java/oji", NULL,
|
||||
new SimplePluginStreamListener(this),
|
||||
nsPluginStreamType_Seek);
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1080,6 +1106,11 @@ native_Simple_printToStdout(JRIEnv* env, struct Simple* self,
|
||||
void
|
||||
SimplePluginInstance::DisplayJavaMessage(char* msg, int len)
|
||||
{
|
||||
#ifdef XP_PC
|
||||
OutputDebugString(msg);
|
||||
OutputDebugString("\n");
|
||||
#endif
|
||||
|
||||
Simple* javaPeer; // instance of the java class (there's no package qualifier)
|
||||
java_lang_String* str;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user