Bug 436663. Work around ATSUI crasher caused by long Hebrew sequence. r=roc, sr=vlad
[wine-gecko.git] / parser / htmlparser / src / nsParserNode.cpp
blob6a4586d2fb14ea667c669b34af5f357ddee23ed3
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
39 #include "nsIAtom.h"
40 #include "nsParserNode.h"
41 #include <string.h>
42 #include "nsHTMLTokens.h"
43 #include "nsITokenizer.h"
44 #include "nsDTDUtils.h"
47 /**
48 * Default Constructor
50 nsCParserNode::nsCParserNode()
51 : mRefCnt(0), mGenericState(PR_FALSE), mUseCount(0), mToken(nsnull),
52 mTokenAllocator(nsnull)
54 MOZ_COUNT_CTOR(nsCParserNode);
55 #ifdef HEAP_ALLOCATED_NODES
56 mNodeAllocator = nsnull;
57 #endif
60 /**
61 * Constructor
63 * @update gess 3/25/98
64 * @param aToken -- token to init internal token
65 * @return
67 nsCParserNode::nsCParserNode(CToken* aToken,
68 nsTokenAllocator* aTokenAllocator,
69 nsNodeAllocator* aNodeAllocator)
70 : mRefCnt(0), mGenericState(PR_FALSE), mUseCount(0), mToken(aToken),
71 mTokenAllocator(aTokenAllocator)
73 MOZ_COUNT_CTOR(nsCParserNode);
75 static int theNodeCount = 0;
76 ++theNodeCount;
77 if (mTokenAllocator) {
78 IF_HOLD(mToken);
79 } // Else a stack-based token
81 #ifdef HEAP_ALLOCATED_NODES
82 mNodeAllocator = aNodeAllocator;
83 #endif
86 /**
87 * destructor
88 * NOTE: We intentionally DON'T recycle mToken here.
89 * It may get cached for use elsewhere
90 * @update gess 3/25/98
91 * @param
92 * @return
94 nsCParserNode::~nsCParserNode() {
95 MOZ_COUNT_DTOR(nsCParserNode);
96 ReleaseAll();
97 #ifdef HEAP_ALLOCATED_NODES
98 if(mNodeAllocator) {
99 mNodeAllocator->Recycle(this);
101 mNodeAllocator = nsnull;
102 #endif
103 mTokenAllocator = 0;
108 * Init
110 * @update gess 3/25/98
111 * @param
112 * @return
115 nsresult
116 nsCParserNode::Init(CToken* aToken,
117 nsTokenAllocator* aTokenAllocator,
118 nsNodeAllocator* aNodeAllocator)
120 mTokenAllocator = aTokenAllocator;
121 mToken = aToken;
122 if (mTokenAllocator) {
123 IF_HOLD(mToken);
124 } // Else a stack-based token
125 mGenericState = PR_FALSE;
126 mUseCount=0;
127 #ifdef HEAP_ALLOCATED_NODES
128 mNodeAllocator = aNodeAllocator;
129 #endif
130 return NS_OK;
133 void
134 nsCParserNode::AddAttribute(CToken* aToken)
140 * Gets the name of this node. Currently unused.
142 * @update gess 3/25/98
143 * @param
144 * @return string ref containing node name
146 const nsAString&
147 nsCParserNode::GetTagName() const {
148 return EmptyString();
153 * Get text value of this node, which translates into
154 * getting the text value of the underlying token
156 * @update gess 3/25/98
157 * @param
158 * @return string ref of text from internal token
160 const nsAString&
161 nsCParserNode::GetText() const
163 if (mToken) {
164 return mToken->GetStringValue();
166 return EmptyString();
170 * Get node type, meaning, get the tag type of the
171 * underlying token
173 * @update gess 3/25/98
174 * @param
175 * @return int value that represents tag type
177 PRInt32
178 nsCParserNode::GetNodeType(void) const
180 return (mToken) ? mToken->GetTypeID() : 0;
185 * Gets the token type, which corresponds to a value from
186 * eHTMLTokens_xxx.
188 * @update gess 3/25/98
189 * @param
190 * @return
192 PRInt32
193 nsCParserNode::GetTokenType(void) const
195 return (mToken) ? mToken->GetTokenType() : 0;
200 * Retrieve the number of attributes on this node
202 * @update gess 3/25/98
203 * @param
204 * @return int -- representing attribute count
206 PRInt32
207 nsCParserNode::GetAttributeCount(PRBool askToken) const
209 return 0;
213 * Retrieve the string rep of the attribute key at the
214 * given index.
216 * @update gess 3/25/98
217 * @param anIndex-- offset of attribute to retrieve
218 * @return string rep of given attribute text key
220 const nsAString&
221 nsCParserNode::GetKeyAt(PRUint32 anIndex) const
223 return EmptyString();
228 * Retrieve the string rep of the attribute at given offset
230 * @update gess 3/25/98
231 * @param anIndex-- offset of attribute to retrieve
232 * @return string rep of given attribute text value
234 const nsAString&
235 nsCParserNode::GetValueAt(PRUint32 anIndex) const
237 return EmptyString();
240 PRInt32
241 nsCParserNode::TranslateToUnicodeStr(nsString& aString) const
243 if (eToken_entity == mToken->GetTokenType()) {
244 return ((CEntityToken*)mToken)->TranslateToUnicodeStr(aString);
246 return -1;
250 * This getter retrieves the line number from the input source where
251 * the token occured. Lines are interpreted as occuring between \n characters.
252 * @update gess7/24/98
253 * @return int containing the line number the token was found on
255 PRInt32
256 nsCParserNode::GetSourceLineNumber(void) const {
257 return mToken ? mToken->GetLineNumber() : 0;
261 * This method pop the attribute token
262 * @update harishd 03/25/99
263 * @return token at anIndex
266 CToken*
267 nsCParserNode::PopAttributeToken() {
268 return 0;
271 CToken*
272 nsCParserNode::PopAttributeTokenFront() {
273 return 0;
276 /** Retrieve a string containing the tag and its attributes in "source" form
277 * @update rickg 06June2000
278 * @return void
280 void
281 nsCParserNode::GetSource(nsString& aString) const
283 eHTMLTags theTag = mToken ? (eHTMLTags)mToken->GetTypeID() : eHTMLTag_unknown;
284 aString.Assign(PRUnichar('<'));
285 const PRUnichar* theTagName = nsHTMLTags::GetStringValue(theTag);
286 if(theTagName) {
287 aString.Append(theTagName);
289 aString.Append(PRUnichar('>'));
292 /** Release all the objects you're holding to.
293 * @update harishd 08/02/00
294 * @return void
296 nsresult
297 nsCParserNode::ReleaseAll()
299 if(mTokenAllocator) {
300 IF_FREE(mToken,mTokenAllocator);
302 return NS_OK;
305 nsresult
306 nsCParserStartNode::Init(CToken* aToken,
307 nsTokenAllocator* aTokenAllocator,
308 nsNodeAllocator* aNodeAllocator)
310 NS_ASSERTION(mAttributes.GetSize() == 0, "attributes not recycled!");
311 return nsCParserNode::Init(aToken, aTokenAllocator, aNodeAllocator);
314 void nsCParserStartNode::AddAttribute(CToken* aToken)
316 NS_ASSERTION(0 != aToken, "Error: Token shouldn't be null!");
317 mAttributes.Push(aToken);
320 PRInt32
321 nsCParserStartNode::GetAttributeCount(PRBool askToken) const
323 PRInt32 result = 0;
324 if (askToken) {
325 result = mToken ? mToken->GetAttributeCount() : 0;
327 else {
328 result = mAttributes.GetSize();
330 return result;
333 const nsAString&
334 nsCParserStartNode::GetKeyAt(PRUint32 anIndex) const
336 if ((PRInt32)anIndex < mAttributes.GetSize()) {
337 CAttributeToken* attr =
338 static_cast<CAttributeToken*>(mAttributes.ObjectAt(anIndex));
339 if (attr) {
340 return attr->GetKey();
343 return EmptyString();
346 const nsAString&
347 nsCParserStartNode::GetValueAt(PRUint32 anIndex) const
349 if (PRInt32(anIndex) < mAttributes.GetSize()) {
350 CAttributeToken* attr =
351 static_cast<CAttributeToken*>(mAttributes.ObjectAt(anIndex));
352 if (attr) {
353 return attr->GetValue();
356 return EmptyString();
359 CToken*
360 nsCParserStartNode::PopAttributeToken()
362 return static_cast<CToken*>(mAttributes.Pop());
365 CToken*
366 nsCParserStartNode::PopAttributeTokenFront()
368 return static_cast<CToken*>(mAttributes.PopFront());
371 void nsCParserStartNode::GetSource(nsString& aString) const
373 aString.Assign(PRUnichar('<'));
374 const PRUnichar* theTagName =
375 nsHTMLTags::GetStringValue(nsHTMLTag(mToken->GetTypeID()));
376 if (theTagName) {
377 aString.Append(theTagName);
379 PRInt32 index;
380 PRInt32 size = mAttributes.GetSize();
381 for (index = 0 ; index < size; ++index) {
382 CAttributeToken *theToken =
383 static_cast<CAttributeToken*>(mAttributes.ObjectAt(index));
384 if (theToken) {
385 theToken->AppendSourceTo(aString);
386 aString.Append(PRUnichar(' ')); //this will get removed...
389 aString.Append(PRUnichar('>'));
392 nsresult nsCParserStartNode::ReleaseAll()
394 NS_ASSERTION(0!=mTokenAllocator, "Error: no token allocator");
395 CToken* theAttrToken;
396 while ((theAttrToken = static_cast<CToken*>(mAttributes.Pop()))) {
397 IF_FREE(theAttrToken, mTokenAllocator);
399 nsCParserNode::ReleaseAll();
400 return NS_OK;