Only allocate and copy a string in CAttributeToken::GetStringValue if the string spans multiple buffers. Otherwise, just wrap it with a nsDependentSubstring. Bug 268932, r=bzbarsky, sr=darin.

git-svn-id: svn://10.0.0.236/trunk@165246 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
bryner%brianryner.com 2004-11-11 03:46:51 +00:00
parent 2d1d00b7e3
commit 0da729e8f7
6 changed files with 49 additions and 37 deletions

View File

@ -698,7 +698,7 @@ PRBool DoesRequireBody(CToken* aToken,nsITokenizer* aTokenizer) {
PRInt32 ac=aToken->GetAttributeCount();
for(PRInt32 i=0; i<ac; ++i) {
CAttributeToken* attr=NS_STATIC_CAST(CAttributeToken*,aTokenizer->GetTokenAt(i));
const nsAString& name=attr->GetKey();
const nsSubstring& name=attr->GetKey();
const nsAString& value=attr->GetValue();
if((name.EqualsLiteral("type") ||
@ -2192,7 +2192,7 @@ nsresult CNavDTD::HandleEntityToken(CToken* aToken) {
nsresult result=NS_OK;
const nsAString& theStr = aToken->GetStringValue();
const nsSubstring& theStr = aToken->GetStringValue();
if((kHashsign!=theStr.First()) && (-1==nsHTMLEntities::EntityToUnicode(theStr))){
CToken *theToken=0;

View File

@ -646,7 +646,7 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,
//start token it was empty.
if(NS_SUCCEEDED(result)) {
PRBool isUsableAttr = PR_TRUE;
const nsAString& key=theToken->GetKey();
const nsSubstring& key=theToken->GetKey();
const nsAString& text=theToken->GetValue();
// support XML like syntax to fix bugs like 44186

View File

@ -208,7 +208,7 @@ nsresult CStartToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aFlag
}
const nsAString& CStartToken::GetStringValue()
const nsSubstring& CStartToken::GetStringValue()
{
if((eHTMLTag_unknown<mTypeID) && (mTypeID<eHTMLTag_text)) {
if(!mTextValue.Length()) {
@ -350,7 +350,7 @@ PRInt32 CEndToken::GetTokenType(void) {
return eToken_end;
}
const nsAString& CEndToken::GetStringValue()
const nsSubstring& CEndToken::GetStringValue()
{
if((eHTMLTag_unknown<mTypeID) && (mTypeID<eHTMLTag_text)) {
if(!mTextValue.Length()) {
@ -631,7 +631,7 @@ void CTextToken::CopyTo(nsAString& aStr)
CopyUnicodeTo(start, end, aStr);
}
const nsAString& CTextToken::GetStringValue(void)
const nsSubstring& CTextToken::GetStringValue(void)
{
return mTextValue.AsString();
}
@ -769,7 +769,7 @@ nsresult CCDATASectionToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt3
return result;
}
const nsAString& CCDATASectionToken::GetStringValue(void)
const nsSubstring& CCDATASectionToken::GetStringValue(void)
{
return mTextValue;
}
@ -905,7 +905,7 @@ nsresult CMarkupDeclToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32
return result;
}
const nsAString& CMarkupDeclToken::GetStringValue(void)
const nsSubstring& CMarkupDeclToken::GetStringValue(void)
{
return mTextValue.AsString();
}
@ -1201,7 +1201,7 @@ nsresult CCommentToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aFl
return result;
}
const nsAString& CCommentToken::GetStringValue(void)
const nsSubstring& CCommentToken::GetStringValue(void)
{
return mComment.AsString();
}
@ -1259,7 +1259,7 @@ void CNewlineToken::FreeNewline()
* @update gess 3/25/98
* @return nsString reference to internal string value
*/
const nsAString& CNewlineToken::GetStringValue(void) {
const nsSubstring& CNewlineToken::GetStringValue(void) {
return gNewlineStr->AsString();
}
@ -1400,12 +1400,7 @@ void CAttributeToken::SanitizeKey() {
return;
}
const nsAString& CAttributeToken::GetKey(void)
{
return mTextKey.AsString();
}
const nsAString& CAttributeToken::GetStringValue(void)
const nsSubstring& CAttributeToken::GetStringValue(void)
{
return mTextValue;
}
@ -1917,7 +1912,7 @@ nsresult CWhitespaceToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32
return result;
}
const nsAString& CWhitespaceToken::GetStringValue(void)
const nsSubstring& CWhitespaceToken::GetStringValue(void)
{
return mTextValue;
}
@ -2178,7 +2173,7 @@ PRInt32 CEntityToken::TranslateToUnicodeStr(nsString& aString) {
}
const nsAString& CEntityToken::GetStringValue(void)
const nsSubstring& CEntityToken::GetStringValue(void)
{
return mTextValue;
}
@ -2299,7 +2294,7 @@ PRInt32 CInstructionToken::GetTokenType(void){
return eToken_instruction;
}
const nsAString& CInstructionToken::GetStringValue(void)
const nsSubstring& CInstructionToken::GetStringValue(void)
{
return mTextValue;
}
@ -2371,7 +2366,7 @@ PRInt32 CDoctypeDeclToken::GetTokenType(void) {
return eToken_doctypeDecl;
}
const nsAString& CDoctypeDeclToken::GetStringValue(void)
const nsSubstring& CDoctypeDeclToken::GetStringValue(void)
{
return mTextValue;
}

View File

@ -235,17 +235,34 @@ nsScannerSubstring::Rebind( const nsAString& aString )
acquire_ownership_of_buffer_list();
}
const nsString&
const nsSubstring&
nsScannerSubstring::AsString() const
{
if (mIsDirty)
{
nsScannerSubstring* mutable_this = NS_CONST_CAST(nsScannerSubstring*, this);
nsScannerIterator start, end;
CopyUnicodeTo(BeginReading(start), EndReading(end), mutable_this->mFlattenedRep);
if (mStart.mBuffer == mEnd.mBuffer) {
// We only have a single fragment to deal with, so just return it
// as a substring. We take advantage of the fact that |nsString| and
// |nsDependentSubstring| don't have any members that aren't on
// |nsSubstring|, so that have same same layout. Furthermore,
// we know that the implementation of ~nsString() will not try
// to free the data if the string was constructed as a
// |nsDependentSubstring|.
mFlattenedRep.~nsString(); // in case we have a buffer currently
new (&mutable_this->mFlattenedRep)
nsDependentSubstring(mStart.mPosition, mEnd.mPosition);
} else {
// Otherwise, we need to copy the data into a flattened buffer.
nsScannerIterator start, end;
CopyUnicodeTo(BeginReading(start), EndReading(end), mutable_this->mFlattenedRep);
}
mutable_this->mIsDirty = PR_FALSE;
}
return mFlattenedRep;
}

View File

@ -181,15 +181,15 @@ public:
mIndirectString=0;
}
void SetIndirectString(const nsAString& aString) {
void SetIndirectString(const nsSubstring& aString) {
mIndirectString=&aString;
}
virtual const nsAString& GetStringValue(void){
return (const nsAString&)*mIndirectString;
virtual const nsSubstring& GetStringValue(void){
return (const nsSubstring&)*mIndirectString;
}
const nsAString* mIndirectString;
const nsSubstring* mIndirectString;
};
@ -954,14 +954,14 @@ nsresult CViewSourceHTML::WriteAttributes(PRInt32 attrCount, PRBool aOwnerInErro
theContext.mTokenNode.AddAttribute(theToken); //and add it to the node.
CAttributeToken* theAttrToken = (CAttributeToken*)theToken;
const nsAString& theKey = theAttrToken->GetKey();
const nsSubstring& theKey = theAttrToken->GetKey();
// The attribute is only in error if its owner is NOT in error.
const PRBool attributeInError =
!aOwnerInError && theAttrToken->IsInError();
result = WriteTag(mKey,theKey,0,attributeInError);
const nsAString& theValue = theAttrToken->GetValue();
const nsSubstring& theValue = theAttrToken->GetValue();
if(!theValue.IsEmpty() || theAttrToken->mHasEqualWithoutValue){
result = WriteTag(mValue,theValue,0,attributeInError);
@ -982,7 +982,7 @@ nsresult CViewSourceHTML::WriteAttributes(PRInt32 attrCount, PRBool aOwnerInErro
* @param
* @return result status
*/
nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsAString & aText,PRInt32 attrCount,PRBool aTagInError) {
nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsSubstring & aText,PRInt32 attrCount,PRBool aTagInError) {
nsresult result=NS_OK;
// adjust line number to what it will be after we finish writing this tag
@ -1132,7 +1132,7 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
{
++mTagCount;
const nsAString& startValue = aToken->GetStringValue();
const nsSubstring& startValue = aToken->GetStringValue();
result=WriteTag(mStartTag,startValue,aToken->GetAttributeCount(),aToken->IsInError());
if((ePlainText!=mDocType) && mParser && (NS_OK==result)) {
@ -1147,7 +1147,7 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
mTags.Truncate(mTags.Length()-1);
}
const nsAString& endValue = aToken->GetStringValue();
const nsSubstring& endValue = aToken->GetStringValue();
result=WriteTag(mEndTag,endValue,aToken->GetAttributeCount(),aToken->IsInError());
}
break;
@ -1186,14 +1186,14 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
case eToken_doctypeDecl:
{
const nsAString& doctypeValue = aToken->GetStringValue();
const nsSubstring& doctypeValue = aToken->GetStringValue();
result=WriteTag(mDocTypeTag,doctypeValue,0,aToken->IsInError());
}
break;
case eToken_newline:
{
const nsAString& newlineValue = aToken->GetStringValue();
const nsSubstring& newlineValue = aToken->GetStringValue();
result=WriteTag(mText,newlineValue,0,PR_FALSE);
++mTokenCount;
if (NS_VIEWSOURCE_TOKENS_PER_BLOCK > 0 &&
@ -1204,7 +1204,7 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
case eToken_whitespace:
{
const nsAString& wsValue = aToken->GetStringValue();
const nsSubstring& wsValue = aToken->GetStringValue();
result=WriteTag(mText,wsValue,0,PR_FALSE);
++mTokenCount;
if (NS_VIEWSOURCE_TOKENS_PER_BLOCK > 0 &&
@ -1219,7 +1219,7 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
case eToken_text:
{
const nsAString& str = aToken->GetStringValue();
const nsSubstring& str = aToken->GetStringValue();
result=WriteTag(mText,str,aToken->GetAttributeCount(),aToken->IsInError());
++mTokenCount;
if (NS_VIEWSOURCE_TOKENS_PER_BLOCK > 0 &&

View File

@ -83,7 +83,7 @@ public:
private:
nsresult WriteTag(PRInt32 tagType,
const nsAString &aText,
const nsSubstring &aText,
PRInt32 attrCount,
PRBool aTagInError);