зеркало из https://github.com/mozilla/pjs.git
This change-bundle applies Darin Fisher's astute observation that CVS
version 1.9 of InputStreamShim.cpp didn't correctly implement QueryInterface. Fixing that allowed me to discover that the system wants to call ::ReadSegments, so I had to implement that. Now the RandomHTMLInputStream case works, but the garden variety FileInputStream case does not. Since the FileInputStream case is generally easier to debug, I'll check in what I have now and continue with this last case tomorrow. M src_moz/InputStreamShim.cpp M src_moz/InputStreamShim.h - made this correctly implement nsIAsyncInputStream. M test/automated/src/classes/org/mozilla/webclient/NavigationTest.java - comment out the FileInputStream case.
This commit is contained in:
Родитель
9a5da5289a
Коммит
8b674e0a55
|
@ -29,7 +29,9 @@
|
|||
#include "prthread.h"
|
||||
|
||||
#include "ns_globals.h"
|
||||
#include "nsMemory.h"
|
||||
|
||||
#include "nsIEventTarget.h"
|
||||
#include "nsStreamUtils.h"
|
||||
|
||||
static const PRInt32 buffer_increment = 5120;
|
||||
static const PRInt32 do_close_code = -524;
|
||||
|
@ -39,7 +41,8 @@ InputStreamShim::InputStreamShim(jobject yourJavaStreamRef,
|
|||
mJavaStream(yourJavaStreamRef), mContentLength(yourContentLength),
|
||||
mBuffer(nsnull), mBufferLength(0), mCountFromJava(0),
|
||||
mCountFromMozilla(0), mAvailable(0), mAvailableForMozilla(0), mNumRead(0),
|
||||
mDoClose(PR_FALSE), mDidClose(PR_FALSE), mLock(nsnull)
|
||||
mDoClose(PR_FALSE), mDidClose(PR_FALSE), mLock(nsnull),
|
||||
mCloseStatus(NS_OK), mCallback(nsnull), mCallbackFlags(0)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
mLock = PR_NewLock();
|
||||
|
@ -56,7 +59,7 @@ InputStreamShim::~InputStreamShim()
|
|||
|
||||
PR_Lock(mLock);
|
||||
|
||||
nsMemory::Free(mBuffer);
|
||||
delete [] mBuffer;
|
||||
mBuffer = nsnull;
|
||||
mBufferLength = 0;
|
||||
|
||||
|
@ -95,13 +98,17 @@ NS_IMETHODIMP_(nsrefcnt) InputStreamShim::Release(void)
|
|||
return mRefCnt;
|
||||
}
|
||||
|
||||
NS_IMPL_QUERY_INTERFACE1(InputStreamShim, nsIInputStream)
|
||||
NS_IMPL_QUERY_INTERFACE2(InputStreamShim,
|
||||
nsIInputStream,
|
||||
nsIAsyncInputStream)
|
||||
|
||||
nsresult InputStreamShim::doReadFromJava()
|
||||
{
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
PR_ASSERT(mLock);
|
||||
|
||||
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
|
||||
("InputStreamShim::doReadFromJava: entering\n"));
|
||||
|
||||
PR_Lock(mLock);
|
||||
|
||||
|
@ -126,6 +133,18 @@ nsresult InputStreamShim::doReadFromJava()
|
|||
}
|
||||
rv = NS_OK;
|
||||
|
||||
// if we have bytes available for mozilla, and they it has requested
|
||||
// a callback when bytes are available.
|
||||
if (mCallback && 0 < mAvailableForMozilla
|
||||
&& !(mCallbackFlags & WAIT_CLOSURE_ONLY)) {
|
||||
rv = mCallback->OnInputStreamReady(this);
|
||||
mCallback = nsnull;
|
||||
mCallbackFlags = nsnull;
|
||||
if (NS_FAILED(rv)) {
|
||||
goto DRFJ_CLEANUP;
|
||||
}
|
||||
}
|
||||
|
||||
// finally, do another check for available bytes
|
||||
if (NS_FAILED(doAvailable())) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
|
@ -144,6 +163,8 @@ nsresult InputStreamShim::doReadFromJava()
|
|||
|
||||
PR_Unlock(mLock);
|
||||
|
||||
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
|
||||
("InputStreamShim::doReadFromJava: exiting\n"));
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -192,12 +213,15 @@ InputStreamShim::doRead(void)
|
|||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
|
||||
("InputStreamShim::doRead: entering\n"));
|
||||
|
||||
PR_ASSERT(0 != mAvailable);
|
||||
|
||||
// if we don't have a buffer, create one
|
||||
if (!mBuffer) {
|
||||
if (0 < mContentLength) {
|
||||
mBuffer = (char *) nsMemory::Alloc(mContentLength);
|
||||
mBuffer = new char[mContentLength];
|
||||
mBufferLength = mContentLength;
|
||||
}
|
||||
else {
|
||||
|
@ -212,7 +236,7 @@ InputStreamShim::doRead(void)
|
|||
mBufferLength = buffer_increment +
|
||||
(bufLengthCalc * buffer_increment);
|
||||
}
|
||||
mBuffer = (char *) nsMemory::Alloc(mBufferLength);
|
||||
mBuffer = new char[mBufferLength];
|
||||
|
||||
}
|
||||
if (!mBuffer) {
|
||||
|
@ -227,22 +251,14 @@ InputStreamShim::doRead(void)
|
|||
|
||||
if (mBufferLength < (mCountFromJava + mAvailable)) {
|
||||
// create the new buffer
|
||||
char *tBuffer = (char *) nsMemory::Alloc(mBufferLength +
|
||||
buffer_increment);
|
||||
char *tBuffer = new char[mBufferLength + buffer_increment];
|
||||
if (!tBuffer) {
|
||||
tBuffer = (char *) malloc(mBufferLength +
|
||||
buffer_increment);
|
||||
if (!tBuffer) {
|
||||
mDoClose = PR_TRUE;
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
// copy the old buffer into the new buffer
|
||||
memcpy(tBuffer, mBuffer, mBufferLength);
|
||||
// delete the old buffer
|
||||
|
||||
nsMemory::Free(mBuffer);
|
||||
|
||||
delete [] mBuffer;
|
||||
// update mBuffer;
|
||||
mBuffer = tBuffer;
|
||||
// update our bufferLength
|
||||
|
@ -282,10 +298,12 @@ InputStreamShim::doRead(void)
|
|||
mCountFromJava += mNumRead;
|
||||
mAvailableForMozilla = mCountFromJava - mCountFromMozilla;
|
||||
}
|
||||
|
||||
rv = NS_OK;
|
||||
#endif
|
||||
|
||||
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
|
||||
("InputStreamShim::doRead: exiting\n"));
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -318,6 +336,13 @@ InputStreamShim::doClose(void)
|
|||
}
|
||||
rv = NS_OK;
|
||||
#endif
|
||||
if (mCallback && mAvailableForMozilla &&
|
||||
!(mCallbackFlags & WAIT_CLOSURE_ONLY)) {
|
||||
rv = mCallback->OnInputStreamReady(this);
|
||||
mCallback = nsnull;
|
||||
mCallbackFlags = nsnull;
|
||||
}
|
||||
|
||||
mDidClose = PR_TRUE;
|
||||
return rv;
|
||||
}
|
||||
|
@ -333,6 +358,9 @@ InputStreamShim::Available(PRUint32* aResult)
|
|||
if (!aResult) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (mDoClose) {
|
||||
return mCloseStatus;
|
||||
}
|
||||
PR_ASSERT(mLock);
|
||||
PR_Lock(mLock);
|
||||
// *aResult = mAvailableForMozilla;
|
||||
|
@ -350,6 +378,7 @@ InputStreamShim::Close()
|
|||
PR_ASSERT(mLock);
|
||||
PR_Lock(mLock);
|
||||
mDoClose = PR_TRUE;
|
||||
mCloseStatus = NS_BASE_STREAM_CLOSED;
|
||||
rv = NS_OK;
|
||||
PR_Unlock(mLock);
|
||||
|
||||
|
@ -363,29 +392,19 @@ InputStreamShim::Read(char* aBuffer, PRUint32 aCount, PRUint32 *aNumRead)
|
|||
if (!aBuffer || !aNumRead) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
|
||||
("InputStreamShim::Read: entering\n"));
|
||||
if (mDoClose) {
|
||||
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
|
||||
("InputStreamShim::Read: exiting, already closed\n"));
|
||||
return mCloseStatus;
|
||||
}
|
||||
*aNumRead = 0;
|
||||
PR_ASSERT(mLock);
|
||||
PR_ASSERT(mCountFromMozilla <= mCountFromJava);
|
||||
|
||||
PR_Lock(mLock);
|
||||
|
||||
// wait for java to load the buffer with some data
|
||||
do {
|
||||
if (mAvailableForMozilla == 0) {
|
||||
PR_Unlock(mLock);
|
||||
PR_Sleep(PR_INTERVAL_MIN);
|
||||
PR_Lock(mLock);
|
||||
if (mDoClose) {
|
||||
PR_Unlock(mLock);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
} while ((!mDidClose) && (-1 != mNumRead));
|
||||
|
||||
if (mAvailableForMozilla) {
|
||||
if (aCount <= (mCountFromJava - mCountFromMozilla)) {
|
||||
// what she's asking for is less than or equal to what we have
|
||||
|
@ -402,27 +421,122 @@ InputStreamShim::Read(char* aBuffer, PRUint32 aCount, PRUint32 *aNumRead)
|
|||
mCountFromMozilla += (mCountFromJava - mCountFromMozilla);
|
||||
}
|
||||
mAvailableForMozilla -= *aNumRead;
|
||||
rv = NS_OK;
|
||||
}
|
||||
else {
|
||||
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
|
||||
("InputStreamShim::Read: exiting, would block\n"));
|
||||
rv = NS_BASE_STREAM_WOULD_BLOCK;
|
||||
}
|
||||
|
||||
rv = NS_OK;
|
||||
PR_Unlock(mLock);
|
||||
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
|
||||
("InputStreamShim::Read: exiting\n"));
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
InputStreamShim::ReadSegments(nsWriteSegmentFun writer, void * closure, PRUint32 count, PRUint32 *_retval)
|
||||
InputStreamShim::ReadSegments(nsWriteSegmentFun writer, void * aClosure,
|
||||
PRUint32 aCount, PRUint32 *aNumRead)
|
||||
{
|
||||
NS_NOTREACHED("ReadSegments");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
if (!writer || !aNumRead) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
|
||||
("InputStreamShim::ReadSegments: entering\n"));
|
||||
if (mDoClose && 0 == mAvailableForMozilla) {
|
||||
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
|
||||
("InputStreamShim::ReadSegments: exiting, already closed\n"));
|
||||
return mCloseStatus;
|
||||
}
|
||||
*aNumRead = 0;
|
||||
PR_ASSERT(mLock);
|
||||
PR_ASSERT(mCountFromMozilla <= mCountFromJava);
|
||||
|
||||
PR_Lock(mLock);
|
||||
|
||||
PRUint32 bytesToWrite = mAvailableForMozilla;
|
||||
PRUint32 bytesWritten;
|
||||
PRUint32 totalBytesWritten = 0;
|
||||
|
||||
if (bytesToWrite > aCount) {
|
||||
bytesToWrite = aCount;
|
||||
}
|
||||
|
||||
if (0 == mAvailableForMozilla) {
|
||||
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
|
||||
("InputStreamShim::Read: exiting, would block\n"));
|
||||
rv = NS_BASE_STREAM_WOULD_BLOCK;
|
||||
}
|
||||
|
||||
while (bytesToWrite) {
|
||||
// what she's asking for is less than or equal to what we have
|
||||
rv = writer(this, aClosure,
|
||||
(mBuffer + mCountFromMozilla),
|
||||
totalBytesWritten, bytesToWrite, &bytesWritten);
|
||||
if (NS_FAILED(rv)) {
|
||||
break;
|
||||
}
|
||||
|
||||
bytesToWrite -= bytesWritten;
|
||||
totalBytesWritten += bytesWritten;
|
||||
mCountFromMozilla += bytesWritten;
|
||||
}
|
||||
|
||||
*aNumRead = totalBytesWritten;
|
||||
mAvailableForMozilla -= totalBytesWritten;
|
||||
|
||||
PR_Unlock(mLock);
|
||||
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
|
||||
("InputStreamShim::ReadSegments: exiting\n"));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
InputStreamShim::IsNonBlocking(PRBool *_retval)
|
||||
{
|
||||
// NS_NOTREACHED("IsNonBlocking");
|
||||
// return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
*_retval = PR_FALSE;
|
||||
*_retval = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
InputStreamShim::CloseWithStatus(nsresult astatus)
|
||||
{
|
||||
this->Close();
|
||||
mCloseStatus = astatus;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
InputStreamShim::AsyncWait(nsIInputStreamCallback *aCallback,
|
||||
PRUint32 aFlags, PRUint32 aRequestedCount,
|
||||
nsIEventTarget *aEventTarget)
|
||||
{
|
||||
PR_Lock(mLock);
|
||||
|
||||
mCallback = nsnull;
|
||||
mCallbackFlags = nsnull;
|
||||
|
||||
nsCOMPtr<nsIInputStreamCallback> proxy;
|
||||
if (aEventTarget) {
|
||||
nsresult rv = NS_NewInputStreamReadyEvent(getter_AddRefs(proxy),
|
||||
aCallback, aEventTarget);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
aCallback = proxy;
|
||||
}
|
||||
if (NS_FAILED(mCloseStatus) ||
|
||||
(mAvailableForMozilla && !(aFlags & WAIT_CLOSURE_ONLY))) {
|
||||
// stream is already closed or readable; post event.
|
||||
aCallback->OnInputStreamReady(this);
|
||||
}
|
||||
else {
|
||||
// queue up callback object to be notified when data becomes available
|
||||
mCallback = aCallback;
|
||||
mCallbackFlags = aFlags;
|
||||
}
|
||||
|
||||
PR_Unlock(mLock);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -22,14 +22,17 @@
|
|||
#ifndef InputStreamShim_h
|
||||
#define InputStreamShim_h
|
||||
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIAsyncInputStream.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
|
||||
|
||||
class InputStreamShimActionEvent;
|
||||
struct PRLock;
|
||||
|
||||
class InputStreamShim : public nsIInputStream
|
||||
class InputStreamShim : public nsIAsyncInputStream
|
||||
{
|
||||
public:
|
||||
InputStreamShim(jobject yourJavaStreamRef,
|
||||
|
@ -77,6 +80,8 @@ private:
|
|||
// nsIInputStream methods
|
||||
NS_DECL_NSIINPUTSTREAM
|
||||
|
||||
// nsIAsyncInputStream
|
||||
NS_DECL_NSIASYNCINPUTSTREAM
|
||||
protected:
|
||||
|
||||
/**
|
||||
|
@ -174,6 +179,12 @@ protected:
|
|||
*/
|
||||
|
||||
PRLock *mLock;
|
||||
|
||||
nsresult mCloseStatus;
|
||||
|
||||
nsCOMPtr<nsIInputStreamCallback> mCallback;
|
||||
|
||||
PRUint32 mCallbackFlags;
|
||||
};
|
||||
|
||||
#endif // InputStreamShim_h
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: NavigationTest.java,v 1.7 2004-06-02 17:26:49 edburns%acm.org Exp $
|
||||
* $Id: NavigationTest.java,v 1.8 2004-06-03 14:28:41 edburns%acm.org Exp $
|
||||
*/
|
||||
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
|
@ -84,7 +84,9 @@ public class NavigationTest extends WebclientTestCase {
|
|||
File testPage = new File(getBrowserBinDir(),
|
||||
"../../java/webclient/test/automated/src/test/NavigationTest.txt");
|
||||
|
||||
//
|
||||
// try loading a file: url
|
||||
//
|
||||
System.out.println("Loading url: " + testPage.toURL().toString());
|
||||
nav.loadURL(testPage.toURL().toString());
|
||||
Thread.currentThread().sleep(1000);
|
||||
|
@ -94,29 +96,36 @@ public class NavigationTest extends WebclientTestCase {
|
|||
assertTrue(-1 != selection.toString().indexOf("This test file is for the NavigationTest."));
|
||||
System.out.println("Selection is: " + selection.toString());
|
||||
|
||||
|
||||
// try loading from a FileInputStream
|
||||
FileInputStream fis = new FileInputStream(testPage);
|
||||
nav.loadFromStream(fis, "http://somefile.com/",
|
||||
"text/html", -1, null);
|
||||
currentPage.selectAll();
|
||||
selection = currentPage.getSelection();
|
||||
assertTrue(-1 != selection.toString().indexOf("This test file is for the NavigationTest."));
|
||||
System.out.println("Selection is: " + selection.toString());
|
||||
|
||||
//
|
||||
// try loading from the dreaded RandomHTMLInputStream
|
||||
RandomHTMLInputStream rhis = new RandomHTMLInputStream(5, false);
|
||||
//
|
||||
RandomHTMLInputStream rhis = new RandomHTMLInputStream(10, false);
|
||||
|
||||
nav.loadFromStreamBlocking(rhis, "http://randomstream.com/",
|
||||
"text/html", -1, null);
|
||||
Thread.currentThread().sleep(15000);
|
||||
|
||||
currentPage.selectAll();
|
||||
selection = currentPage.getSelection();
|
||||
System.out.println("Selection is: " + selection.toString());
|
||||
|
||||
/***********
|
||||
//
|
||||
// try loading from a FileInputStream
|
||||
//
|
||||
FileInputStream fis = new FileInputStream(testPage);
|
||||
nav.loadFromStream(fis, "http://somefile.com/",
|
||||
"text/html", -1, null);
|
||||
boolean keepWaiting = true;
|
||||
//while (keepWaiting) {
|
||||
Thread.currentThread().sleep(8000);
|
||||
Thread.currentThread().sleep(15000);
|
||||
//}
|
||||
|
||||
currentPage.selectAll();
|
||||
selection = currentPage.getSelection();
|
||||
assertTrue(-1 != selection.toString().indexOf("This test file is for the NavigationTest."));
|
||||
System.out.println("Selection is: " + selection.toString());
|
||||
*******************/
|
||||
|
||||
frame.setVisible(false);
|
||||
BrowserControlFactory.deleteBrowserControl(firstBrowserControl);
|
||||
|
|
Загрузка…
Ссылка в новой задаче