Bug 643590 - Convert nsJSON::DecodeFromStream to buffer all JSON data, then process it all in one swell foop once it's all received. r=jst

This commit is contained in:
Jeff Walden 2011-03-21 11:42:14 -07:00
Родитель af47ba19ae
Коммит 27dffbdba3
2 изменённых файлов: 18 добавлений и 35 удалений

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

@ -573,7 +573,6 @@ nsJSONListener::nsJSONListener(JSContext *cx, jsval *rootVal,
PRBool needsConverter,
DecodingMode mode /* = STRICT */)
: mNeedsConverter(needsConverter),
mJSONParser(nsnull),
mCx(cx),
mRootVal(rootVal),
mDecodingMode(mode)
@ -582,7 +581,6 @@ nsJSONListener::nsJSONListener(JSContext *cx, jsval *rootVal,
nsJSONListener::~nsJSONListener()
{
Cleanup();
}
NS_INTERFACE_MAP_BEGIN(nsJSONListener)
@ -599,9 +597,6 @@ nsJSONListener::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
{
mSniffBuffer.Truncate();
mDecoder = nsnull;
mJSONParser = JS_BeginJSONParse(mCx, mRootVal);
if (!mJSONParser)
return NS_ERROR_FAILURE;
return NS_OK;
}
@ -618,13 +613,13 @@ nsJSONListener::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
NS_ENSURE_SUCCESS(rv, rv);
}
JSBool ok = JS_FinishJSONParse(mCx, mJSONParser, JSVAL_NULL);
mJSONParser = nsnull;
if (!ok)
return NS_ERROR_FAILURE;
return NS_OK;
const jschar* chars = reinterpret_cast<const jschar*>(mBufferedChars.Elements());
JSBool ok = js::ParseJSONWithReviver(mCx, chars,
(uint32) mBufferedChars.Length(),
js::NullValue(), js::Valueify(mRootVal),
mDecodingMode);
mBufferedChars.TruncateLength(0);
return ok ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
@ -721,34 +716,23 @@ nsJSONListener::ConsumeConverted(const char* aBuffer, PRUint32 aByteLength)
rv = mDecoder->GetMaxLength(aBuffer, srcLen, &unicharLength);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoArrayPtr<PRUnichar> ustr(new PRUnichar[unicharLength]);
NS_ENSURE_TRUE(ustr, NS_ERROR_OUT_OF_MEMORY);
rv = mDecoder->Convert(aBuffer, &srcLen, ustr, &unicharLength);
NS_ENSURE_SUCCESS(rv, rv);
rv = Consume(ustr.get(), unicharLength);
return rv;
}
void nsJSONListener::Cleanup()
{
if (mJSONParser)
JS_FinishJSONParse(mCx, mJSONParser, JSVAL_NULL);
mJSONParser = nsnull;
PRUnichar* endelems = mBufferedChars.AppendElements(unicharLength);
PRInt32 preLength = unicharLength;
rv = mDecoder->Convert(aBuffer, &srcLen, endelems, &unicharLength);
if (NS_FAILED(rv))
return rv;
NS_ABORT_IF_FALSE(preLength >= unicharLength, "GetMaxLength lied");
if (preLength > unicharLength)
mBufferedChars.TruncateLength(mBufferedChars.Length() - (preLength - unicharLength));
return NS_OK;
}
nsresult
nsJSONListener::Consume(const PRUnichar* aBuffer, PRUint32 aByteLength)
{
if (!mJSONParser)
if (!mBufferedChars.AppendElements(aBuffer, aByteLength))
return NS_ERROR_FAILURE;
if (!js_ConsumeJSONText(mCx, mJSONParser, (jschar*) aBuffer, aByteLength,
mDecodingMode)) {
Cleanup();
return NS_ERROR_FAILURE;
}
return NS_OK;
}

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

@ -111,16 +111,15 @@ public:
protected:
PRBool mNeedsConverter;
JSONParser *mJSONParser;
JSContext *mCx;
jsval *mRootVal;
nsCOMPtr<nsIUnicodeDecoder> mDecoder;
nsCString mSniffBuffer;
nsTArray<PRUnichar> mBufferedChars;
DecodingMode mDecodingMode;
nsresult ProcessBytes(const char* aBuffer, PRUint32 aByteLength);
nsresult ConsumeConverted(const char* aBuffer, PRUint32 aByteLength);
nsresult Consume(const PRUnichar *data, PRUint32 len);
void Cleanup();
};
#endif