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:
parent
6a15277f8f
commit
fe32860667
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user