fixes bug 190549 "Textarea with lots of text within refuses to submit"
r=sicking sr=bzbarsky a=asa git-svn-id: svn://10.0.0.236/trunk@137068 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -55,11 +55,9 @@ interface nsIInputStream;
|
||||
* Implementers should return the following:
|
||||
*
|
||||
* @return NS_OK and (*aWriteCount > 0) if consumed some data
|
||||
* @return NS_BASE_STREAM_WOULD_BLOCK if not interested in consuming any data
|
||||
* @return <other-error> on failure
|
||||
* @return <any-error> if not interested in consuming any data
|
||||
*
|
||||
* Errors are passed to the caller of ReadSegments, unless aToOffset is
|
||||
* greater than zero.
|
||||
* Errors are never passed to the caller of ReadSegments.
|
||||
*
|
||||
* NOTE: returning NS_OK and (*aWriteCount = 0) has undefined behavior.
|
||||
*
|
||||
@@ -99,7 +97,7 @@ interface nsIInputStream : nsISupports
|
||||
* @param aBuf the buffer into which the data is to be read
|
||||
* @param aCount the maximum number of bytes to be read
|
||||
*
|
||||
* @return number of bytes read
|
||||
* @return number of bytes read (may be less than aCount).
|
||||
* @return 0 if reached end of file
|
||||
*
|
||||
* @throws NS_BASE_STREAM_WOULD_BLOCK if reading from the input stream would
|
||||
@@ -109,15 +107,18 @@ interface nsIInputStream : nsISupports
|
||||
[noscript] unsigned long read(in charPtr aBuf, in unsigned long aCount);
|
||||
|
||||
/**
|
||||
* Low-level read method that has access to the stream's underlying buffer. The
|
||||
* writer function may be called multiple times for segmented buffers.
|
||||
* Low-level read method that has access to the stream's underlying buffer.
|
||||
* The writer function may be called multiple times for segmented buffers.
|
||||
* ReadSegments is expected to keep calling the writer until either there is
|
||||
* nothing left to read or the writer returns an error. ReadSegments should
|
||||
* not call the writer with zero bytes to consume.
|
||||
*
|
||||
* @param aWriter the "consumer" of the data to be read
|
||||
* @param aClosure opaque parameter passed to writer
|
||||
* @param aCount the maximum number of bytes to be read
|
||||
*
|
||||
* @return number of bytes read
|
||||
* @return 0 if reached end of file
|
||||
* @return number of bytes read (may be less than aCount)
|
||||
* @return 0 if reached end of file (or if aWriter refused to consume data)
|
||||
*
|
||||
* @throws NS_BASE_STREAM_WOULD_BLOCK if reading from the input stream would
|
||||
* block the calling thread (non-blocking mode only)
|
||||
|
||||
@@ -57,11 +57,9 @@ interface nsIInputStream;
|
||||
*
|
||||
* @return NS_OK and (*aReadCount > 0) if successfully provided some data
|
||||
* @return NS_OK and (*aReadCount = 0) or
|
||||
* @return NS_BASE_STREAM_WOULD_BLOCK if not interested in providing any data
|
||||
* @return <other-error> on failure
|
||||
* @return <any-error> if not interested in providing any data
|
||||
*
|
||||
* Errors are passed to the caller of WriteSegments, unless aFromOffset is
|
||||
* greater than zero.
|
||||
* Errors are never passed to the caller of WriteSegments.
|
||||
*
|
||||
* @status FROZEN
|
||||
*/
|
||||
@@ -105,7 +103,7 @@ interface nsIOutputStream : nsISupports
|
||||
* @param aBuf the buffer containing the data to be written
|
||||
* @param aCount the maximum number of bytes to be written
|
||||
*
|
||||
* @return number of bytes written
|
||||
* @return number of bytes written (may be less than aCount)
|
||||
*
|
||||
* @throws NS_BASE_STREAM_WOULD_BLOCK if writing to the output stream would
|
||||
* block the calling thread (non-blocking mode only)
|
||||
@@ -119,7 +117,7 @@ interface nsIOutputStream : nsISupports
|
||||
* @param aFromStream the stream containing the data to be written
|
||||
* @param aCount the maximum number of bytes to be written
|
||||
*
|
||||
* @return number of bytes written
|
||||
* @return number of bytes written (may be less than aCount)
|
||||
*
|
||||
* @throws NS_BASE_STREAM_WOULD_BLOCK if writing to the output stream would
|
||||
* block the calling thread (non-blocking mode only)
|
||||
@@ -135,14 +133,17 @@ interface nsIOutputStream : nsISupports
|
||||
in unsigned long aCount);
|
||||
|
||||
/**
|
||||
* Low-level write method that has access to the stream's underlying buffer. The
|
||||
* reader function may be called multiple times for segmented buffers.
|
||||
* Low-level write method that has access to the stream's underlying buffer.
|
||||
* The reader function may be called multiple times for segmented buffers.
|
||||
* WriteSegments is expected to keep calling the reader until either there
|
||||
* is nothing left to write or the reader returns an error. WriteSegments
|
||||
* should not call the reader with zero bytes to provide.
|
||||
*
|
||||
* @param aReader the "provider" of the data to be written
|
||||
* @param aClosure opaque parameter passed to reader
|
||||
* @param aCount the maximum number of bytes to be written
|
||||
*
|
||||
* @return number of bytes written
|
||||
* @return number of bytes written (may be less than aCount)
|
||||
*
|
||||
* @throws NS_BASE_STREAM_WOULD_BLOCK if writing to the output stream would
|
||||
* block the calling thread (non-blocking mode only)
|
||||
@@ -157,6 +158,9 @@ interface nsIOutputStream : nsISupports
|
||||
|
||||
/**
|
||||
* @return true if stream is non-blocking
|
||||
*
|
||||
* NOTE: writing to a blocking output stream will block the calling thread
|
||||
* until all given data can be consumed by the stream.
|
||||
*/
|
||||
boolean isNonBlocking();
|
||||
};
|
||||
|
||||
@@ -187,34 +187,38 @@ nsMultiplexInputStream::Available(PRUint32 *_retval)
|
||||
NS_IMETHODIMP
|
||||
nsMultiplexInputStream::Read(char * aBuf, PRUint32 aCount, PRUint32 *_retval)
|
||||
{
|
||||
nsresult rv;
|
||||
PRUint32 len;
|
||||
nsresult rv = NS_OK;
|
||||
PRUint32 len, read;
|
||||
|
||||
*_retval = 0;
|
||||
|
||||
mStreams.Count(&len);
|
||||
PRUint32 read = 0;
|
||||
while (mCurrentStream < len && aCount > 0) {
|
||||
while (mCurrentStream < len && aCount) {
|
||||
nsCOMPtr<nsIInputStream> stream(do_QueryElementAt(&mStreams,
|
||||
mCurrentStream));
|
||||
rv = stream->Read(aBuf, aCount, _retval);
|
||||
if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
|
||||
*_retval = read;
|
||||
return read == 0 ? NS_BASE_STREAM_WOULD_BLOCK : NS_OK;
|
||||
rv = stream->Read(aBuf, aCount, &read);
|
||||
|
||||
// XXX some streams return NS_BASE_STREAM_CLOSED to indicate EOF.
|
||||
if (rv == NS_BASE_STREAM_CLOSED) {
|
||||
rv = NS_OK;
|
||||
read = 0;
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!*_retval) {
|
||||
// we're done with this stream, proceed to next
|
||||
else if (NS_FAILED(rv))
|
||||
break;
|
||||
|
||||
if (read == 0) {
|
||||
++mCurrentStream;
|
||||
mStartedReadingCurrent = PR_FALSE;
|
||||
}
|
||||
else {
|
||||
read += *_retval;
|
||||
aBuf += *_retval;
|
||||
aCount -= *_retval;
|
||||
NS_ASSERTION(aCount >= read, "Read more than requested");
|
||||
*_retval += read;
|
||||
aCount -= read;
|
||||
aBuf += read;
|
||||
mStartedReadingCurrent = PR_TRUE;
|
||||
}
|
||||
}
|
||||
*_retval = read;
|
||||
return NS_OK;
|
||||
return *_retval ? NS_OK : rv;
|
||||
}
|
||||
|
||||
/* [noscript] unsigned long readSegments (in nsWriteSegmentFun writer,
|
||||
@@ -226,7 +230,7 @@ nsMultiplexInputStream::ReadSegments(nsWriteSegmentFun aWriter, void *aClosure,
|
||||
{
|
||||
NS_ASSERTION(aWriter, "missing aWriter");
|
||||
|
||||
nsresult rv;
|
||||
nsresult rv = NS_OK;
|
||||
ReadSegmentsState state;
|
||||
state.mThisStream = this;
|
||||
state.mOffset = 0;
|
||||
@@ -236,46 +240,38 @@ nsMultiplexInputStream::ReadSegments(nsWriteSegmentFun aWriter, void *aClosure,
|
||||
|
||||
PRUint32 len;
|
||||
mStreams.Count(&len);
|
||||
while (mCurrentStream < len) {
|
||||
while (mCurrentStream < len && aCount) {
|
||||
nsCOMPtr<nsIInputStream> stream(do_QueryElementAt(&mStreams,
|
||||
mCurrentStream));
|
||||
PRUint32 read;
|
||||
rv = stream->ReadSegments(ReadSegCb, &state, aCount, &read);
|
||||
// If we got an NS_BASE_STREAM_WOULD_BLOCK error since the reader
|
||||
// didn't want any more data. This might not be an error for us if
|
||||
// data was read from a previous stream in this run
|
||||
if (state.mDone && rv == NS_BASE_STREAM_WOULD_BLOCK &&
|
||||
!read && state.mOffset)
|
||||
break;
|
||||
|
||||
// If the return value is NS_BASE_STREAM_CLOSED, we are done with this
|
||||
// stream.
|
||||
// XXX some streams return NS_BASE_STREAM_CLOSED to indicate EOF.
|
||||
if (rv == NS_BASE_STREAM_CLOSED) {
|
||||
++mCurrentStream;
|
||||
mStartedReadingCurrent = PR_FALSE;
|
||||
continue;
|
||||
rv = NS_OK;
|
||||
read = 0;
|
||||
}
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ASSERTION(aCount >= read, "Read more than requested");
|
||||
mStartedReadingCurrent = PR_TRUE;
|
||||
state.mOffset += read;
|
||||
aCount -= read;
|
||||
if (state.mDone || // writer doesn't want anymore data
|
||||
aCount == 0) // the current stream still has data
|
||||
// if |aWriter| decided to stop reading segments...
|
||||
if (state.mDone || NS_FAILED(rv))
|
||||
break;
|
||||
|
||||
// If the writer accepted all data but we didn't read any, this stream
|
||||
// is finished. Go on to the next stream. These aren't the droids
|
||||
// you're looking for.
|
||||
|
||||
// if stream is empty, then advance to the next stream.
|
||||
if (read == 0) {
|
||||
++mCurrentStream;
|
||||
mStartedReadingCurrent = PR_FALSE;
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(aCount >= read, "Read more than requested");
|
||||
state.mOffset += read;
|
||||
aCount -= read;
|
||||
mStartedReadingCurrent = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// if we successfully read some data, then this call succeeded.
|
||||
*_retval = state.mOffset;
|
||||
return NS_OK;
|
||||
return state.mOffset ? NS_OK : rv;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
@@ -292,10 +288,8 @@ nsMultiplexInputStream::ReadSegCb(nsIInputStream* aIn, void* aClosure,
|
||||
aToOffset + state->mOffset,
|
||||
aCount,
|
||||
aWriteCount);
|
||||
if (rv == NS_BASE_STREAM_WOULD_BLOCK ||
|
||||
(NS_SUCCEEDED(rv) && *aWriteCount < aCount && aCount != 0))
|
||||
if (NS_FAILED(rv))
|
||||
state->mDone = PR_TRUE;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
@@ -408,10 +408,10 @@ NS_AsyncCopy(nsIAsyncInputStream *source,
|
||||
//
|
||||
// fire off two async copies :-)
|
||||
//
|
||||
rv = NS_AsyncCopy(source, pipeOut, segmentSize, PR_FALSE, PR_TRUE);
|
||||
rv = NS_AsyncCopy(source, pipeOut, PR_FALSE, PR_TRUE, segmentSize, 1, segmentAlloc);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = NS_AsyncCopy(pipeIn, sink, segmentSize, PR_TRUE, PR_FALSE);
|
||||
rv = NS_AsyncCopy(pipeIn, sink, PR_TRUE, PR_FALSE, segmentSize, 1, segmentAlloc);
|
||||
|
||||
// maybe calling NS_AsyncCopy twice is a bad idea!
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "uh-oh");
|
||||
|
||||
@@ -312,6 +312,10 @@ class ConstCharImpl
|
||||
PRUint32 aCount, PRUint32 *result) {
|
||||
nsresult rv;
|
||||
PRInt32 maxCount = mLength - mOffset;
|
||||
if (maxCount == 0) {
|
||||
*result = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
if ((PRInt32)aCount > maxCount)
|
||||
aCount = maxCount;
|
||||
rv = writer(this, closure, mConstString + mOffset,
|
||||
|
||||
Reference in New Issue
Block a user