Fixed up input stream buffering. Fixed some refcounting problems.

This commit is contained in:
warren%netscape.com 1998-10-01 08:08:09 +00:00
parent f44e8829c5
commit c4eaaf4ebe
5 changed files with 162 additions and 42 deletions

View File

@ -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;

View File

@ -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));
}

View File

@ -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;
};

View File

@ -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

View File

@ -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;