Make it possible to use the string input stream without heap-allocating a

string.  Bug 263973, r=darin, sr=dbaron


git-svn-id: svn://10.0.0.236/trunk@164487 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
bzbarsky%mit.edu 2004-10-27 02:19:43 +00:00
parent 6a15277f8f
commit fe32860667
5 changed files with 88 additions and 99 deletions

View File

@ -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<nsIUnicharInputStream> 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;
}

View File

@ -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<nsIUnicharInputStream> 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<nsIUnicharInputStream> 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<nsIUnicharInputStream> input = nsnull;
nsresult rv = NS_NewStringUnicharInputStream(getter_AddRefs(input), str);
nsCOMPtr<nsIUnicharInputStream> 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<nsIUnicharInputStream> 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;
}

View File

@ -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<nsIUnicharInputStream> 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<nsIUnicharInputStream> 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<nsIUnicharInputStream> input = nsnull;
nsresult rv = NS_NewStringUnicharInputStream(getter_AddRefs(input), str);
nsCOMPtr<nsIUnicharInputStream> 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<nsIUnicharInputStream> 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;
}

View File

@ -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

View File

@ -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;
}
//----------------------------------------------------------------------