Fixing bug 267854. Make sure parser data listeners get all the data that comes in from necko, no matter what the current parser context is. r=bzbarsky@mit.edu, sr=brendan@mozilla.org

This commit is contained in:
jst%mozilla.jstenback.com 2004-11-05 06:50:27 +00:00
Родитель 8c1a8602e0
Коммит 97b6debb17
4 изменённых файлов: 69 добавлений и 62 удалений

Просмотреть файл

@ -1493,12 +1493,12 @@ void nsParser::HandleParserContinueEvent() {
ContinueParsing();
}
nsresult nsParser::DataAdded(const nsSubstring& aData)
nsresult nsParser::DataAdded(const nsSubstring& aData, nsIRequest *aRequest)
{
NS_ASSERTION(sParserDataListeners,
"Don't call this with no parser data listeners!");
if (!mSink || !mParserContext || !mParserContext->mRequest) {
if (!mSink || !aRequest) {
return NS_OK;
}
@ -1509,10 +1509,10 @@ nsresult nsParser::DataAdded(const nsSubstring& aData)
while (count--) {
rv |= sParserDataListeners->ObjectAt(count)->
OnUnicharDataAvailable(mParserContext->mRequest, ctx, aData);
OnUnicharDataAvailable(aRequest, ctx, aData);
if (NS_FAILED(rv) && !canceled) {
mParserContext->mRequest->Cancel(rv);
aRequest->Cancel(rv);
canceled = PR_TRUE;
}
@ -2437,7 +2437,7 @@ typedef struct {
/*
* This function is invoked as a result of a call to a stream's
* ReadSegments() method. It is called for each contiguous buffer
* ReadSegments() method. It is called for each contiguous buffer
* of data in the underlying stream or pipe. Using ReadSegments
* allows us to avoid copying data to read out of the stream.
*/
@ -2458,17 +2458,16 @@ ParserWriteFunc(nsIInputStream* in,
return NS_ERROR_FAILURE;
}
if(pws->mNeedCharsetCheck) {
if (pws->mNeedCharsetCheck) {
PRInt32 guessSource;
nsCAutoString guess;
nsCAutoString preferred;
pws->mNeedCharsetCheck = PR_FALSE;
if(pws->mParser->DetectMetaTag(buf, theNumRead,
guess, guessSource) ||
((count >= 4) &&
DetectByteOrderMark((const unsigned char*)buf,
theNumRead, guess, guessSource))) {
nsCAutoString preferred;
pws->mNeedCharsetCheck = PR_FALSE;
if (pws->mParser->DetectMetaTag(buf, theNumRead, guess, guessSource) ||
((count >= 4) &&
DetectByteOrderMark((const unsigned char*)buf,
theNumRead, guess, guessSource))) {
nsCOMPtr<nsICharsetAlias> alias(do_GetService(NS_CHARSETALIAS_CONTRACTID));
result = alias->GetPreferred(guess, preferred);
// Only continue if it's a recognized charset and not
@ -2481,7 +2480,7 @@ ParserWriteFunc(nsIInputStream* in,
!preferred.EqualsLiteral("UTF-32BE") &&
!preferred.EqualsLiteral("UTF-32LE")))) {
guess = preferred;
pws->mParser->SetDocumentCharset(guess, guessSource);
pws->mParser->SetDocumentCharset(guess, guessSource);
pws->mParser->SetSinkCharset(preferred);
nsCOMPtr<nsICachingChannel> channel(do_QueryInterface(pws->mRequest));
if (channel) {
@ -2500,13 +2499,13 @@ ParserWriteFunc(nsIInputStream* in,
}
}
}
}
}
}
}
if(pws->mParserFilter)
pws->mParserFilter->RawBuffer(buf, &theNumRead);
if (pws->mParserFilter)
pws->mParserFilter->RawBuffer(buf, &theNumRead);
result = pws->mScanner->Append(buf, theNumRead);
result = pws->mScanner->Append(buf, theNumRead, pws->mRequest);
if (NS_SUCCEEDED(result)) {
*writeCount = count;
}
@ -2523,60 +2522,59 @@ ParserWriteFunc(nsIInputStream* in,
* @return error code (usually 0)
*/
nsresult nsParser::OnDataAvailable(nsIRequest *request, nsISupports* aContext,
nsIInputStream *pIStream, PRUint32 sourceOffset, PRUint32 aLength)
{
NS_PRECONDITION((eOnStart == mParserContext->mStreamListenerState ||
eOnDataAvail == mParserContext->mStreamListenerState),
nsresult nsParser::OnDataAvailable(nsIRequest *request, nsISupports* aContext,
nsIInputStream *pIStream,
PRUint32 sourceOffset, PRUint32 aLength)
{
NS_PRECONDITION((eOnStart == mParserContext->mStreamListenerState ||
eOnDataAvail == mParserContext->mStreamListenerState),
"Error: OnStartRequest() must be called before OnDataAvailable()");
nsresult result=NS_OK;
nsresult rv = NS_OK;
CParserContext *theContext=mParserContext;
while(theContext) {
if(theContext->mRequest!=request && theContext->mPrevContext)
theContext=theContext->mPrevContext;
else break;
}
CParserContext *theContext=mParserContext;
if(theContext && theContext->mRequest==request) {
while (theContext) {
if (theContext->mRequest != request && theContext->mPrevContext)
theContext = theContext->mPrevContext;
else break;
}
theContext->mStreamListenerState=eOnDataAvail;
if (theContext && theContext->mRequest == request) {
if(eInvalidDetect==theContext->mAutoDetectStatus) {
if(theContext->mScanner) {
theContext->mStreamListenerState = eOnDataAvail;
if (eInvalidDetect == theContext->mAutoDetectStatus) {
if (theContext->mScanner) {
nsScannerIterator iter;
theContext->mScanner->EndReading(iter);
theContext->mScanner->SetPosition(iter, PR_TRUE);
}
}
}
}
PRUint32 totalRead;
ParserWriteStruct pws;
pws.mNeedCharsetCheck =
((0 == sourceOffset) && (mCharsetSource<kCharsetFromMetaTag));
pws.mNeedCharsetCheck =
(0 == sourceOffset) && (mCharsetSource < kCharsetFromMetaTag);
pws.mParser = this;
pws.mParserFilter = mParserFilter;
pws.mScanner = theContext->mScanner;
pws.mRequest = request;
result = pIStream->ReadSegments(ParserWriteFunc, (void*)&pws, aLength, &totalRead);
if (NS_FAILED(result)) {
return result;
rv = pIStream->ReadSegments(ParserWriteFunc, &pws, aLength, &totalRead);
if (NS_FAILED(rv)) {
return rv;
}
// Don't bother to start parsing until we've seen some
// non-whitespace data
if (theContext->mScanner->FirstNonWhitespacePosition() >= 0) {
result = ResumeParse();
rv = ResumeParse();
}
}
return result;
}
return rv;
}
/**
* This is called by the networking library once the last block of data

Просмотреть файл

@ -389,7 +389,7 @@ class nsParser : public nsIParser,
* Called by top-level scanners when data from necko is added to
* the scanner.
*/
nsresult DataAdded(const nsSubstring& aData);
nsresult DataAdded(const nsSubstring& aData, nsIRequest *aRequest);
static nsCOMArray<nsIUnicharStreamListener> *sParserDataListeners;

Просмотреть файл

@ -342,7 +342,9 @@ nsresult nsScanner::Append(const nsAString& aBuffer) {
* @param
* @return
*/
nsresult nsScanner::Append(const char* aBuffer, PRUint32 aLen){
nsresult nsScanner::Append(const char* aBuffer, PRUint32 aLen,
nsIRequest *aRequest)
{
nsresult res=NS_OK;
PRUnichar *unichars, *start;
if(mUnicodeDecoder) {
@ -391,7 +393,7 @@ nsresult nsScanner::Append(const char* aBuffer, PRUint32 aLen){
} while (NS_FAILED(res) && (aLen > 0));
buffer->SetDataLength(totalChars);
AppendToBuffer(buffer);
AppendToBuffer(buffer, aRequest);
mTotalRead += totalChars;
// Don't propagate return code of unicode decoder
@ -400,7 +402,7 @@ nsresult nsScanner::Append(const char* aBuffer, PRUint32 aLen){
res = NS_OK;
}
else {
AppendASCIItoBuffer(aBuffer, aLen);
AppendASCIItoBuffer(aBuffer, aLen, aRequest);
mTotalRead+=aLen;
}
@ -445,7 +447,7 @@ nsresult nsScanner::FillBuffer(void) {
}
if((0<numread) && (0==result)) {
AppendASCIItoBuffer(buf, numread);
AppendASCIItoBuffer(buf, numread, nsnull);
}
mTotalRead+=numread;
}
@ -1329,11 +1331,12 @@ void nsScanner::ReplaceCharacter(nsScannerIterator& aPosition,
}
}
void nsScanner::AppendToBuffer(nsScannerString::Buffer* aBuf)
void nsScanner::AppendToBuffer(nsScannerString::Buffer* aBuf,
nsIRequest *aRequest)
{
if (nsParser::sParserDataListeners && mParser &&
NS_FAILED(mParser->DataAdded(Substring(aBuf->DataStart(),
aBuf->DataEnd())))) {
aBuf->DataEnd()), aRequest))) {
// Don't actually append on failure.
return;
@ -1371,7 +1374,8 @@ void nsScanner::AppendToBuffer(nsScannerString::Buffer* aBuf)
}
}
void nsScanner::AppendASCIItoBuffer(const char* aData, PRUint32 aLen)
void nsScanner::AppendASCIItoBuffer(const char* aData, PRUint32 aLen,
nsIRequest *aRequest)
{
nsScannerString::Buffer* buf = nsScannerString::AllocBuffer(aLen);
if (buf)
@ -1379,7 +1383,7 @@ void nsScanner::AppendASCIItoBuffer(const char* aData, PRUint32 aLen)
LossyConvertEncoding<char, PRUnichar> converter(buf->DataStart());
converter.write(aData, aLen);
converter.write_terminator();
AppendToBuffer(buf);
AppendToBuffer(buf, aRequest);
}
}

Просмотреть файл

@ -304,7 +304,8 @@ class nsScanner {
* @param
* @return
*/
nsresult Append(const char* aBuffer, PRUint32 aLen);
nsresult Append(const char* aBuffer, PRUint32 aLen,
nsIRequest *aRequest);
/**
* Call this to copy bytes out of the scanner that have not yet been consumed
@ -384,9 +385,13 @@ class nsScanner {
*/
nsresult FillBuffer(void);
void AppendToBuffer(nsScannerString::Buffer*);
void AppendToBuffer(const nsAString& aStr) { AppendToBuffer(nsScannerString::AllocBufferFromString(aStr)); }
void AppendASCIItoBuffer(const char* aData, PRUint32 aLen);
void AppendToBuffer(nsScannerString::Buffer *, nsIRequest *aRequest);
void AppendToBuffer(const nsAString& aStr)
{
AppendToBuffer(nsScannerString::AllocBufferFromString(aStr), nsnull);
}
void AppendASCIItoBuffer(const char* aData, PRUint32 aLen,
nsIRequest *aRequest);
nsCOMPtr<nsIInputStream> mInputStream;
nsScannerString* mSlidingBuffer;