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.


git-svn-id: svn://10.0.0.236/trunk@157361 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
edburns%acm.org
2004-06-03 14:28:41 +00:00
parent aa9dc3f484
commit a8e6c2aaee
3 changed files with 197 additions and 63 deletions

View File

@@ -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;
}
rv = NS_OK;
else {
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
("InputStreamShim::Read: exiting, would block\n"));
rv = NS_BASE_STREAM_WOULD_BLOCK;
}
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;
}