diff --git a/mozilla/content/base/src/nsStyleLinkElement.cpp b/mozilla/content/base/src/nsStyleLinkElement.cpp index 3c818a0bc6b..0f78b5bd777 100644 --- a/mozilla/content/base/src/nsStyleLinkElement.cpp +++ b/mozilla/content/base/src/nsStyleLinkElement.cpp @@ -294,8 +294,7 @@ nsStyleLinkElement::UpdateStyleSheet(nsIDocument *aOldDocument, if (isInline) { PRUint32 count = thisContent->GetChildCount(); - nsString *content = new nsString(); - NS_ENSURE_TRUE(content, NS_ERROR_OUT_OF_MEMORY); + nsAutoString content; PRUint32 i; for (i = 0; i < count; ++i) { @@ -312,13 +311,15 @@ nsStyleLinkElement::UpdateStyleSheet(nsIDocument *aOldDocument, nsAutoString tcString; tc->GetData(tcString); - content->Append(tcString); + content.Append(tcString); } + // Use of the stream will be done before parsing returns. So it will go + // out of scope before |content| does. nsCOMPtr uin; - rv = NS_NewStringUnicharInputStream(getter_AddRefs(uin), content); + rv = NS_NewStringUnicharInputStream(getter_AddRefs(uin), &content, + PR_FALSE); if (NS_FAILED(rv)) { - delete content; return rv; } diff --git a/mozilla/content/html/style/src/nsCSSParser.cpp b/mozilla/content/html/style/src/nsCSSParser.cpp index 01a76e8dffe..4587a2b57c1 100644 --- a/mozilla/content/html/style/src/nsCSSParser.cpp +++ b/mozilla/content/html/style/src/nsCSSParser.cpp @@ -639,21 +639,16 @@ CSSParserImpl::ParseStyleAttribute(const nsAString& aAttributeValue, { NS_ASSERTION(nsnull != aBaseURL, "need base URL"); - // XXXldb XXXperf nsIUnicharInputStream is horrible! It makes us make - // a copy. - nsString* str = new nsAutoString(aAttributeValue); - if (nsnull == str) { - return NS_ERROR_OUT_OF_MEMORY; - } - nsIUnicharInputStream* input = nsnull; - nsresult rv = NS_NewStringUnicharInputStream(&input, str); - if (NS_OK != rv) { - delete str; + nsCOMPtr input; + // Style attribute parsing can't make the stream outlive this + // function call, so having it not own the string is OK. + nsresult rv = NS_NewStringUnicharInputStream(getter_AddRefs(input), + &aAttributeValue, PR_FALSE); + if (NS_FAILED(rv)) { return rv; } rv = InitScanner(input, aDocURL, 0, aBaseURL); // XXX line number - NS_RELEASE(input); if (! NS_SUCCEEDED(rv)) { return rv; } @@ -707,19 +702,16 @@ CSSParserImpl::ParseAndAppendDeclaration(const nsAString& aBuffer, // NS_ASSERTION(nsnull != aBaseURL, "need base URL"); *aChanged = PR_FALSE; - nsString* str = new nsString(aBuffer); - if (nsnull == str) { - return NS_ERROR_OUT_OF_MEMORY; - } - nsIUnicharInputStream* input = nsnull; - nsresult rv = NS_NewStringUnicharInputStream(&input, str); - if (NS_OK != rv) { - delete str; + nsCOMPtr input; + // Parsing a single declaration block can't make the stream outlive this + // function call, so having it not own the string is OK. + nsresult rv = NS_NewStringUnicharInputStream(getter_AddRefs(input), + &aBuffer, PR_FALSE); + if (NS_FAILED(rv)) { return rv; } rv = InitScanner(input, aSheetURL, 0, aBaseURL); - NS_RELEASE(input); if (! NS_SUCCEEDED(rv)) { return rv; } @@ -766,14 +758,12 @@ CSSParserImpl::ParseRule(const nsAString& aRule, NS_ASSERTION(nsnull != aBaseURL, "need base URL"); NS_ENSURE_ARG_POINTER(aResult); - nsString* str = new nsString(aRule); - if (nsnull == str) { - return NS_ERROR_OUT_OF_MEMORY; - } - nsCOMPtr input = nsnull; - nsresult rv = NS_NewStringUnicharInputStream(getter_AddRefs(input), str); + nsCOMPtr input; + // Parsing a single rule can't make the stream outlive this + // function call, so having it not own the string is OK. + nsresult rv = NS_NewStringUnicharInputStream(getter_AddRefs(input), + &aRule, PR_FALSE); if (NS_FAILED(rv)) { - delete str; return rv; } @@ -824,15 +814,12 @@ CSSParserImpl::ParseProperty(const nsCSSProperty aPropID, NS_ASSERTION(nsnull != aDeclaration, "Need declaration to parse into!"); *aChanged = PR_FALSE; - nsString* str = new nsAutoString(aPropValue); - if (!str) { - return NS_ERROR_OUT_OF_MEMORY; - } - nsCOMPtr input; - nsresult rv = NS_NewStringUnicharInputStream(getter_AddRefs(input), str); + // Parsing a single property value can't make the stream outlive this + // function call, so having it not own the string is OK. + nsresult rv = NS_NewStringUnicharInputStream(getter_AddRefs(input), + &aPropValue, PR_FALSE); if (NS_FAILED(rv)) { - delete str; return rv; } diff --git a/mozilla/layout/style/nsCSSParser.cpp b/mozilla/layout/style/nsCSSParser.cpp index 01a76e8dffe..4587a2b57c1 100644 --- a/mozilla/layout/style/nsCSSParser.cpp +++ b/mozilla/layout/style/nsCSSParser.cpp @@ -639,21 +639,16 @@ CSSParserImpl::ParseStyleAttribute(const nsAString& aAttributeValue, { NS_ASSERTION(nsnull != aBaseURL, "need base URL"); - // XXXldb XXXperf nsIUnicharInputStream is horrible! It makes us make - // a copy. - nsString* str = new nsAutoString(aAttributeValue); - if (nsnull == str) { - return NS_ERROR_OUT_OF_MEMORY; - } - nsIUnicharInputStream* input = nsnull; - nsresult rv = NS_NewStringUnicharInputStream(&input, str); - if (NS_OK != rv) { - delete str; + nsCOMPtr input; + // Style attribute parsing can't make the stream outlive this + // function call, so having it not own the string is OK. + nsresult rv = NS_NewStringUnicharInputStream(getter_AddRefs(input), + &aAttributeValue, PR_FALSE); + if (NS_FAILED(rv)) { return rv; } rv = InitScanner(input, aDocURL, 0, aBaseURL); // XXX line number - NS_RELEASE(input); if (! NS_SUCCEEDED(rv)) { return rv; } @@ -707,19 +702,16 @@ CSSParserImpl::ParseAndAppendDeclaration(const nsAString& aBuffer, // NS_ASSERTION(nsnull != aBaseURL, "need base URL"); *aChanged = PR_FALSE; - nsString* str = new nsString(aBuffer); - if (nsnull == str) { - return NS_ERROR_OUT_OF_MEMORY; - } - nsIUnicharInputStream* input = nsnull; - nsresult rv = NS_NewStringUnicharInputStream(&input, str); - if (NS_OK != rv) { - delete str; + nsCOMPtr input; + // Parsing a single declaration block can't make the stream outlive this + // function call, so having it not own the string is OK. + nsresult rv = NS_NewStringUnicharInputStream(getter_AddRefs(input), + &aBuffer, PR_FALSE); + if (NS_FAILED(rv)) { return rv; } rv = InitScanner(input, aSheetURL, 0, aBaseURL); - NS_RELEASE(input); if (! NS_SUCCEEDED(rv)) { return rv; } @@ -766,14 +758,12 @@ CSSParserImpl::ParseRule(const nsAString& aRule, NS_ASSERTION(nsnull != aBaseURL, "need base URL"); NS_ENSURE_ARG_POINTER(aResult); - nsString* str = new nsString(aRule); - if (nsnull == str) { - return NS_ERROR_OUT_OF_MEMORY; - } - nsCOMPtr input = nsnull; - nsresult rv = NS_NewStringUnicharInputStream(getter_AddRefs(input), str); + nsCOMPtr input; + // Parsing a single rule can't make the stream outlive this + // function call, so having it not own the string is OK. + nsresult rv = NS_NewStringUnicharInputStream(getter_AddRefs(input), + &aRule, PR_FALSE); if (NS_FAILED(rv)) { - delete str; return rv; } @@ -824,15 +814,12 @@ CSSParserImpl::ParseProperty(const nsCSSProperty aPropID, NS_ASSERTION(nsnull != aDeclaration, "Need declaration to parse into!"); *aChanged = PR_FALSE; - nsString* str = new nsAutoString(aPropValue); - if (!str) { - return NS_ERROR_OUT_OF_MEMORY; - } - nsCOMPtr input; - nsresult rv = NS_NewStringUnicharInputStream(getter_AddRefs(input), str); + // Parsing a single property value can't make the stream outlive this + // function call, so having it not own the string is OK. + nsresult rv = NS_NewStringUnicharInputStream(getter_AddRefs(input), + &aPropValue, PR_FALSE); if (NS_FAILED(rv)) { - delete str; return rv; } diff --git a/mozilla/xpcom/io/nsIUnicharInputStream.h b/mozilla/xpcom/io/nsIUnicharInputStream.h index 7232249d80c..2b29ef44189 100644 --- a/mozilla/xpcom/io/nsIUnicharInputStream.h +++ b/mozilla/xpcom/io/nsIUnicharInputStream.h @@ -74,12 +74,14 @@ public: /** * Create a nsIUnicharInputStream that wraps up a string. Data is fed * from the string out until the done. When this object is destroyed - * it destroyes the string (so make a copy if you don't want it doing - * that) + * it destroys the string by calling |delete| on the pointer if + * aTakeOwnership is set. If aTakeOwnership is not set, you must + * ensure that the string outlives the stream! */ extern NS_COM nsresult NS_NewStringUnicharInputStream(nsIUnicharInputStream** aInstancePtrResult, - nsString* aString); + const nsAString* aString, + PRBool aTakeOwnerhip); /** Create a new nsUnicharInputStream that provides a converter for the * byte input stream aStreamToWrap. If no converter can be found then diff --git a/mozilla/xpcom/io/nsUnicharInputStream.cpp b/mozilla/xpcom/io/nsUnicharInputStream.cpp index 99e9364a9ee..034d36bca41 100644 --- a/mozilla/xpcom/io/nsUnicharInputStream.cpp +++ b/mozilla/xpcom/io/nsUnicharInputStream.cpp @@ -52,7 +52,8 @@ class StringUnicharInputStream : public nsIUnicharInputStream { public: - StringUnicharInputStream(nsString* aString); + StringUnicharInputStream(const nsAString* aString, + PRBool aTakeOwnership); NS_DECL_ISUPPORTS @@ -64,25 +65,30 @@ public: PRUint32 aCount, PRUint32* aReadCount); NS_IMETHOD Close(); - nsString* mString; + const nsAString* mString; PRUint32 mPos; PRUint32 mLen; + PRBool mOwnsString; private: ~StringUnicharInputStream(); }; -StringUnicharInputStream::StringUnicharInputStream(nsString* aString) +StringUnicharInputStream::StringUnicharInputStream(const nsAString* aString, + PRBool aTakeOwnership) + : mString(aString), + mPos(0), + mLen(aString->Length()), + mOwnsString(aTakeOwnership) { - mString = aString; - mPos = 0; - mLen = aString->Length(); } StringUnicharInputStream::~StringUnicharInputStream() { - if (nsnull != mString) { - delete mString; + if (mString && mOwnsString) { + // Some compilers dislike deleting const pointers + nsAString* mutable_string = NS_CONST_CAST(nsAString*, mString); + delete mutable_string; } } @@ -95,7 +101,9 @@ StringUnicharInputStream::Read(PRUnichar* aBuf, *aReadCount = 0; return NS_OK; } - const PRUnichar* us = mString->get(); + nsAString::const_iterator iter; + mString->BeginReading(iter); + const PRUnichar* us = iter.get(); NS_ASSERTION(mLen >= mPos, "unsigned madness"); PRUint32 amount = mLen - mPos; if (amount > aCount) { @@ -118,8 +126,11 @@ StringUnicharInputStream::ReadSegments(nsWriteUnicharSegmentFun aWriter, nsresult rv; aCount = PR_MIN(mString->Length() - mPos, aCount); + nsAString::const_iterator iter; + mString->BeginReading(iter); + while (aCount) { - rv = aWriter(this, aClosure, mString->get() + mPos, + rv = aWriter(this, aClosure, iter.get() + mPos, totalBytesWritten, aCount, &bytesWritten); if (NS_FAILED(rv)) { @@ -140,10 +151,12 @@ StringUnicharInputStream::ReadSegments(nsWriteUnicharSegmentFun aWriter, nsresult StringUnicharInputStream::Close() { mPos = mLen; - if (nsnull != mString) { - delete mString; - mString = 0; + if (mString && mOwnsString) { + // Some compilers dislike deleting const pointers + nsAString* mutable_string = NS_CONST_CAST(nsAString*, mString); + delete mutable_string; } + mString = nsnull; return NS_OK; } @@ -151,21 +164,20 @@ NS_IMPL_ISUPPORTS1(StringUnicharInputStream, nsIUnicharInputStream) NS_COM nsresult NS_NewStringUnicharInputStream(nsIUnicharInputStream** aInstancePtrResult, - nsString* aString) + const nsAString* aString, + PRBool aTakeOwnership) { - NS_PRECONDITION(nsnull != aString, "null ptr"); - NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr"); - if ((nsnull == aString) || (nsnull == aInstancePtrResult)) { - return NS_ERROR_NULL_POINTER; - } + NS_ENSURE_ARG_POINTER(aString); + NS_PRECONDITION(aInstancePtrResult, "null ptr"); - StringUnicharInputStream* it = new StringUnicharInputStream(aString); - if (nsnull == it) { + StringUnicharInputStream* it = new StringUnicharInputStream(aString, + aTakeOwnership); + if (!it) { return NS_ERROR_OUT_OF_MEMORY; } - return it->QueryInterface(NS_GET_IID(nsIUnicharInputStream), - (void**) aInstancePtrResult); + NS_ADDREF(*aInstancePtrResult = it); + return NS_OK; } //----------------------------------------------------------------------