mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-05 08:35:26 +00:00
0e44edc9ef
java/dom/jni/org_mozilla_dom_events_MouseEventImpl.cpp java/dom/jni/org_mozilla_dom_events_UIEventImpl.cpp java/dom/jni/org_mozilla_dom_events_EventImpl.cpp java/dom/jni/org_mozilla_dom_ProcessingInstructionImpl.cpp java/dom/jni/org_mozilla_dom_NodeImpl.cpp java/dom/jni/org_mozilla_dom_NamedNodeMapImpl.cpp java/dom/jni/org_mozilla_dom_ElementImpl.cpp java/dom/jni/org_mozilla_dom_DOMImplementationImpl.cpp java/dom/jni/org_mozilla_dom_DocumentImpl.cpp java/dom/jni/org_mozilla_dom_CharacterDataImpl.cpp java/dom/jni/org_mozilla_dom_AttrImpl.cpp java/dom/jni/javaDOMEventsGlobals.cpp // On*DocumentLoad() now takes an nsIRequest instead of an nsIChannel. // nsIChannel extends nsIRequest. java/dom/src/nsJavaDOMImpl.cpp java/dom/src/nsJavaDOMImpl.h java/dom/src/nsIJavaDOM.h // nsIChannel instances replaced with nsIRequest. Removed ShowModal(), // ExitModalLoop(), FindNamedBrowserItem(). Parameter changes for // {Set,Get}Persistence(). Add DestroyBrowserWindow(), IsWindowModal(). // supports weak references java/webclient/src_moz/CBrowserContainer.h java/webclient/src_moz/CBrowserContainer.cpp // GetProfileList now returns an array of profile names. Need to use // nsIProfileInternal instead of nsIProfile for StartupWithArgs. java/webclient/src_moz/NativeEventThread.cpp // Remove -lxpfelocation_s java/webclient/src_moz/Makefile.in // Don't include appfilelocprovider_s java/webclient/src_moz/Makefile.win // Don't assert thread safe, cause we are thread safe java/webclient/src_moz/InputStreamShim.cpp
415 lines
11 KiB
C++
415 lines
11 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
* The contents of this file are subject to the Netscape Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is Mozilla Communicator client code, released
|
|
* March 31, 1998.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
*/
|
|
|
|
#include "InputStreamShim.h"
|
|
|
|
#include "jni_util.h"
|
|
|
|
#include "nsCRT.h"
|
|
#include "prlock.h"
|
|
#include "prlog.h"
|
|
#include "prthread.h"
|
|
|
|
static const PRInt32 buffer_increment = 1024;
|
|
static const PRInt32 do_close_code = -524;
|
|
|
|
InputStreamShim::InputStreamShim(jobject yourJavaStreamRef,
|
|
PRInt32 yourContentLength) :
|
|
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)
|
|
{
|
|
NS_INIT_REFCNT();
|
|
mLock = PR_NewLock();
|
|
JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION);
|
|
}
|
|
|
|
InputStreamShim::~InputStreamShim()
|
|
{
|
|
JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION);
|
|
::util_DeleteGlobalRef(env, mJavaStream);
|
|
mJavaStream = nsnull;
|
|
|
|
mContentLength = -1;
|
|
|
|
delete [] mBuffer;
|
|
mBuffer = nsnull;
|
|
mBufferLength = 0;
|
|
|
|
mAvailable = 0;
|
|
mAvailableForMozilla = 0;
|
|
mNumRead = 0;
|
|
mDoClose = PR_TRUE;
|
|
mDidClose = PR_TRUE;
|
|
PR_DestroyLock(mLock);
|
|
mLock = nsnull;
|
|
}
|
|
|
|
//NS_IMPL_ISUPPORTS(InputStreamShim, NS_GET_IID(nsIInputStream))
|
|
NS_IMETHODIMP_(nsrefcnt) InputStreamShim::AddRef(void)
|
|
{
|
|
NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt");
|
|
// Note that we intentionally don't check for owning thread safety.
|
|
++mRefCnt;
|
|
NS_LOG_ADDREF(this, mRefCnt, "InputStreamShim", sizeof(*this));
|
|
return mRefCnt;
|
|
}
|
|
|
|
NS_IMETHODIMP_(nsrefcnt) InputStreamShim::Release(void)
|
|
{
|
|
NS_PRECONDITION(0 != mRefCnt, "dup release");
|
|
// Note that we intentionally don't check for owning thread safety.
|
|
--mRefCnt;
|
|
NS_LOG_RELEASE(this, mRefCnt, "InputStreamShim");
|
|
if (mRefCnt == 0) {
|
|
mRefCnt = 1; /* stabilize */
|
|
NS_DELETEXPCOM(this);
|
|
return 0;
|
|
}
|
|
return mRefCnt;
|
|
}
|
|
|
|
NS_IMPL_QUERY_INTERFACE(InputStreamShim, NS_GET_IID(nsIInputStream))
|
|
|
|
nsresult InputStreamShim::doReadFromJava()
|
|
{
|
|
nsresult rv = NS_ERROR_FAILURE;
|
|
PR_ASSERT(mLock);
|
|
|
|
PR_Lock(mLock);
|
|
|
|
// first, see how much data is available
|
|
if (NS_FAILED(rv = doAvailable())) {
|
|
goto DRFJ_CLEANUP;
|
|
}
|
|
|
|
// if we have all our data, give the error appropriate result
|
|
if (0 == mAvailable ||
|
|
(0 != mCountFromJava &&
|
|
(((PRUint32)mContentLength) == mCountFromJava))) {
|
|
mDoClose = PR_TRUE;
|
|
doClose();
|
|
rv = NS_ERROR_NOT_AVAILABLE;
|
|
goto DRFJ_CLEANUP;
|
|
}
|
|
|
|
if (NS_FAILED(doRead())) {
|
|
rv = NS_ERROR_FAILURE;
|
|
goto DRFJ_CLEANUP;
|
|
}
|
|
rv = NS_OK;
|
|
|
|
// finally, do another check for available bytes
|
|
if (NS_FAILED(doAvailable())) {
|
|
rv = NS_ERROR_FAILURE;
|
|
goto DRFJ_CLEANUP;
|
|
}
|
|
if (0 == mAvailable ||
|
|
(0 != mCountFromJava &&
|
|
(((PRUint32)mContentLength) == mCountFromJava))) {
|
|
mDoClose = PR_TRUE;
|
|
doClose();
|
|
rv = NS_ERROR_NOT_AVAILABLE;
|
|
goto DRFJ_CLEANUP;
|
|
}
|
|
|
|
DRFJ_CLEANUP:
|
|
|
|
PR_Unlock(mLock);
|
|
return rv;
|
|
}
|
|
|
|
//
|
|
// Helper methods called from doReadFromJava
|
|
//
|
|
|
|
nsresult
|
|
InputStreamShim::doAvailable(void)
|
|
{
|
|
nsresult rv = NS_ERROR_FAILURE;
|
|
if (mDidClose) {
|
|
mAvailable = 0;
|
|
return NS_OK;
|
|
}
|
|
#ifdef BAL_INTERFACE
|
|
#else
|
|
JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION);
|
|
jclass streamClass = nsnull;
|
|
jmethodID mid = nsnull;
|
|
|
|
if (!(streamClass = env->GetObjectClass(mJavaStream))) {
|
|
return rv;
|
|
}
|
|
if (!(mid = env->GetMethodID(streamClass, "available", "()I"))) {
|
|
return rv;
|
|
}
|
|
mAvailable = (PRUint32) env->CallIntMethod(mJavaStream, mid);
|
|
if (env->ExceptionOccurred()) {
|
|
env->ExceptionDescribe();
|
|
env->ExceptionClear();
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
rv = NS_OK;
|
|
#endif
|
|
|
|
return rv;
|
|
}
|
|
|
|
nsresult
|
|
InputStreamShim::doRead(void)
|
|
{
|
|
nsresult rv = NS_ERROR_FAILURE;
|
|
if (mDoClose) {
|
|
doClose();
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
PR_ASSERT(0 != mAvailable);
|
|
|
|
// if we don't have a buffer, create one
|
|
if (!mBuffer) {
|
|
if (0 < mContentLength) {
|
|
mBuffer = new char[mContentLength];
|
|
mBufferLength = mContentLength;
|
|
}
|
|
else {
|
|
|
|
// make sure we allocate enough buffer to store what is
|
|
// currently available.
|
|
if (mAvailable < buffer_increment) {
|
|
mBufferLength = buffer_increment;
|
|
}
|
|
else {
|
|
PRInt32 bufLengthCalc = mAvailable / buffer_increment;
|
|
mBufferLength = buffer_increment +
|
|
(bufLengthCalc * buffer_increment);
|
|
}
|
|
mBuffer = new char[mBufferLength];
|
|
|
|
}
|
|
if (!mBuffer) {
|
|
mBufferLength = 0;
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
}
|
|
else {
|
|
|
|
// See if we need to grow our buffer. If what we have plus what
|
|
// we're about to get is greater than the current buffer size...
|
|
|
|
if (mBufferLength < (mCountFromJava + mAvailable)) {
|
|
// create the new buffer
|
|
char *tBuffer = new char[mBufferLength + buffer_increment];
|
|
if (!tBuffer) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
// copy the old buffer into the new buffer
|
|
nsCRT::memcpy(tBuffer, mBuffer, mBufferLength);
|
|
// delete the old buffer
|
|
delete [] mBuffer;
|
|
// update mBuffer;
|
|
mBuffer = tBuffer;
|
|
// update our bufferLength
|
|
mBufferLength += buffer_increment;
|
|
}
|
|
}
|
|
|
|
#ifdef BAL_INTERFACE
|
|
#else
|
|
JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION);
|
|
jmethodID mid = nsnull;
|
|
jclass streamClass = nsnull;
|
|
jbyteArray javaByteArray = nsnull;
|
|
|
|
if (!(streamClass = env->GetObjectClass(mJavaStream))) {
|
|
return rv;
|
|
}
|
|
if (!(mid = env->GetMethodID(streamClass, "read", "([BII)I"))) {
|
|
return rv;
|
|
}
|
|
|
|
if (!(javaByteArray = env->NewByteArray((jsize) mAvailable))) {
|
|
return rv;
|
|
}
|
|
|
|
mNumRead = env->CallIntMethod(mJavaStream, mid, javaByteArray, (jint) 0,
|
|
(jint) mAvailable);
|
|
if (env->ExceptionOccurred()) {
|
|
env->ExceptionDescribe();
|
|
env->ExceptionClear();
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
if (0 < mNumRead) {
|
|
// copy the bytes from java into our buffer
|
|
env->GetByteArrayRegion(javaByteArray, 0, (jint) mNumRead,
|
|
(jbyte *) (mBuffer + mCountFromJava));
|
|
mCountFromJava += mNumRead;
|
|
mAvailableForMozilla = mCountFromJava - mCountFromMozilla;
|
|
}
|
|
rv = NS_OK;
|
|
#endif
|
|
return rv;
|
|
}
|
|
|
|
nsresult
|
|
InputStreamShim::doClose(void)
|
|
{
|
|
nsresult rv = NS_ERROR_FAILURE;
|
|
PR_ASSERT(mDoClose);
|
|
if (mDidClose) {
|
|
return NS_OK;
|
|
}
|
|
|
|
#ifdef BAL_INTERFACE
|
|
#else
|
|
JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION);
|
|
jclass streamClass = nsnull;
|
|
jmethodID mid = nsnull;
|
|
|
|
if (!(streamClass = env->GetObjectClass(mJavaStream))) {
|
|
return rv;
|
|
}
|
|
if (!(mid = env->GetMethodID(streamClass, "close", "()V"))) {
|
|
return rv;
|
|
}
|
|
env->CallVoidMethod(mJavaStream, mid);
|
|
if (env->ExceptionOccurred()) {
|
|
env->ExceptionDescribe();
|
|
env->ExceptionClear();
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
rv = NS_OK;
|
|
#endif
|
|
mDidClose = PR_TRUE;
|
|
return rv;
|
|
}
|
|
|
|
//
|
|
// nsIInputStream methods
|
|
//
|
|
|
|
NS_IMETHODIMP
|
|
InputStreamShim::Available(PRUint32* aResult)
|
|
{
|
|
nsresult rv = NS_ERROR_FAILURE;
|
|
if (!aResult) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
PR_ASSERT(mLock);
|
|
PR_Lock(mLock);
|
|
*aResult = mAvailableForMozilla;
|
|
rv = NS_OK;
|
|
PR_Unlock(mLock);
|
|
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
InputStreamShim::Close()
|
|
{
|
|
nsresult rv = NS_ERROR_FAILURE;
|
|
PR_ASSERT(mLock);
|
|
PR_Lock(mLock);
|
|
mDoClose = PR_TRUE;
|
|
rv = NS_OK;
|
|
PR_Unlock(mLock);
|
|
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
InputStreamShim::Read(char* aBuffer, PRUint32 aCount, PRUint32 *aNumRead)
|
|
{
|
|
nsresult rv = NS_ERROR_FAILURE;
|
|
if (!aBuffer || !aNumRead) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
*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);
|
|
}
|
|
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
|
|
nsCRT::memcpy(aBuffer, (mBuffer + mCountFromMozilla), aCount);
|
|
mCountFromMozilla += aCount;
|
|
*aNumRead = aCount;
|
|
}
|
|
else {
|
|
// what she's asking for is more than what we have
|
|
nsCRT::memcpy(aBuffer, (mBuffer + mCountFromMozilla),
|
|
(mCountFromJava - mCountFromMozilla));
|
|
*aNumRead = (mCountFromJava - mCountFromMozilla);
|
|
|
|
mCountFromMozilla += (mCountFromJava - mCountFromMozilla);
|
|
}
|
|
mAvailableForMozilla -= *aNumRead;
|
|
}
|
|
|
|
rv = NS_OK;
|
|
PR_Unlock(mLock);
|
|
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
InputStreamShim::ReadSegments(nsWriteSegmentFun writer, void * closure, PRUint32 count, PRUint32 *_retval)
|
|
{
|
|
NS_NOTREACHED("ReadSegments");
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
InputStreamShim::GetNonBlocking(PRBool *aNonBlocking)
|
|
{
|
|
NS_NOTREACHED("GetNonBlocking");
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
InputStreamShim::GetObserver(nsIInputStreamObserver * *aObserver)
|
|
{
|
|
NS_NOTREACHED("GetObserver");
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
InputStreamShim::SetObserver(nsIInputStreamObserver * aObserver)
|
|
{
|
|
NS_NOTREACHED("SetObserver");
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|