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
4 : *
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/
9 : *
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.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
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.
21 : *
22 : * Contributor(s):
23 : *
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.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 :
39 : #include "nsIAtom.h"
40 : #include "nsParserNode.h"
41 : #include <string.h>
42 : #include "nsHTMLTokens.h"
43 : #include "nsITokenizer.h"
44 : #include "nsDTDUtils.h"
45 :
46 :
47 : /**
48 : * Default Constructor
49 : */
50 0 : nsCParserNode::nsCParserNode()
51 : : mRefCnt(0), mGenericState(false), mUseCount(0), mToken(nsnull),
52 0 : mTokenAllocator(nsnull)
53 : {
54 0 : MOZ_COUNT_CTOR(nsCParserNode);
55 : #ifdef HEAP_ALLOCATED_NODES
56 : mNodeAllocator = nsnull;
57 : #endif
58 0 : }
59 :
60 : /**
61 : * Constructor
62 : *
63 : * @update gess 3/25/98
64 : * @param aToken -- token to init internal token
65 : * @return
66 : */
67 1967 : nsCParserNode::nsCParserNode(CToken* aToken,
68 : nsTokenAllocator* aTokenAllocator,
69 : nsNodeAllocator* aNodeAllocator)
70 : : mRefCnt(0), mGenericState(false), mUseCount(0), mToken(aToken),
71 1967 : mTokenAllocator(aTokenAllocator)
72 : {
73 1967 : MOZ_COUNT_CTOR(nsCParserNode);
74 :
75 : static int theNodeCount = 0;
76 1967 : ++theNodeCount;
77 1967 : if (mTokenAllocator) {
78 1967 : IF_HOLD(mToken);
79 : } // Else a stack-based token
80 :
81 : #ifdef HEAP_ALLOCATED_NODES
82 : mNodeAllocator = aNodeAllocator;
83 : #endif
84 1967 : }
85 :
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
93 : */
94 1967 : nsCParserNode::~nsCParserNode() {
95 1967 : MOZ_COUNT_DTOR(nsCParserNode);
96 1967 : ReleaseAll();
97 : #ifdef HEAP_ALLOCATED_NODES
98 : if(mNodeAllocator) {
99 : mNodeAllocator->Recycle(this);
100 : }
101 : mNodeAllocator = nsnull;
102 : #endif
103 1967 : mTokenAllocator = 0;
104 1967 : }
105 :
106 :
107 : /**
108 : * Init
109 : *
110 : * @update gess 3/25/98
111 : * @param
112 : * @return
113 : */
114 :
115 : nsresult
116 0 : nsCParserNode::Init(CToken* aToken,
117 : nsTokenAllocator* aTokenAllocator,
118 : nsNodeAllocator* aNodeAllocator)
119 : {
120 0 : mTokenAllocator = aTokenAllocator;
121 0 : mToken = aToken;
122 0 : if (mTokenAllocator) {
123 0 : IF_HOLD(mToken);
124 : } // Else a stack-based token
125 0 : mGenericState = false;
126 0 : mUseCount=0;
127 : #ifdef HEAP_ALLOCATED_NODES
128 : mNodeAllocator = aNodeAllocator;
129 : #endif
130 0 : return NS_OK;
131 : }
132 :
133 : void
134 0 : nsCParserNode::AddAttribute(CToken* aToken)
135 : {
136 0 : }
137 :
138 :
139 : /**
140 : * Gets the name of this node. Currently unused.
141 : *
142 : * @update gess 3/25/98
143 : * @param
144 : * @return string ref containing node name
145 : */
146 : const nsAString&
147 0 : nsCParserNode::GetTagName() const {
148 0 : return EmptyString();
149 : }
150 :
151 :
152 : /**
153 : * Get text value of this node, which translates into
154 : * getting the text value of the underlying token
155 : *
156 : * @update gess 3/25/98
157 : * @param
158 : * @return string ref of text from internal token
159 : */
160 : const nsAString&
161 306 : nsCParserNode::GetText() const
162 : {
163 306 : if (mToken) {
164 306 : return mToken->GetStringValue();
165 : }
166 0 : return EmptyString();
167 : }
168 :
169 : /**
170 : * Get node type, meaning, get the tag type of the
171 : * underlying token
172 : *
173 : * @update gess 3/25/98
174 : * @param
175 : * @return int value that represents tag type
176 : */
177 : PRInt32
178 4784 : nsCParserNode::GetNodeType(void) const
179 : {
180 4784 : return (mToken) ? mToken->GetTypeID() : 0;
181 : }
182 :
183 :
184 : /**
185 : * Gets the token type, which corresponds to a value from
186 : * eHTMLTokens_xxx.
187 : *
188 : * @update gess 3/25/98
189 : * @param
190 : * @return
191 : */
192 : PRInt32
193 0 : nsCParserNode::GetTokenType(void) const
194 : {
195 0 : return (mToken) ? mToken->GetTokenType() : 0;
196 : }
197 :
198 :
199 : /**
200 : * Retrieve the number of attributes on this node
201 : *
202 : * @update gess 3/25/98
203 : * @param
204 : * @return int -- representing attribute count
205 : */
206 : PRInt32
207 0 : nsCParserNode::GetAttributeCount(bool askToken) const
208 : {
209 0 : return 0;
210 : }
211 :
212 : /**
213 : * Retrieve the string rep of the attribute key at the
214 : * given index.
215 : *
216 : * @update gess 3/25/98
217 : * @param anIndex-- offset of attribute to retrieve
218 : * @return string rep of given attribute text key
219 : */
220 : const nsAString&
221 0 : nsCParserNode::GetKeyAt(PRUint32 anIndex) const
222 : {
223 0 : return EmptyString();
224 : }
225 :
226 :
227 : /**
228 : * Retrieve the string rep of the attribute at given offset
229 : *
230 : * @update gess 3/25/98
231 : * @param anIndex-- offset of attribute to retrieve
232 : * @return string rep of given attribute text value
233 : */
234 : const nsAString&
235 0 : nsCParserNode::GetValueAt(PRUint32 anIndex) const
236 : {
237 0 : return EmptyString();
238 : }
239 :
240 : PRInt32
241 0 : nsCParserNode::TranslateToUnicodeStr(nsString& aString) const
242 : {
243 0 : if (eToken_entity == mToken->GetTokenType()) {
244 0 : return ((CEntityToken*)mToken)->TranslateToUnicodeStr(aString);
245 : }
246 0 : return -1;
247 : }
248 :
249 : /**
250 : * This getter retrieves the line number from the input source where
251 : * the token occurred. Lines are interpreted as occurring between \n characters.
252 : * @update gess7/24/98
253 : * @return int containing the line number the token was found on
254 : */
255 : PRInt32
256 0 : nsCParserNode::GetSourceLineNumber(void) const {
257 0 : return mToken ? mToken->GetLineNumber() : 0;
258 : }
259 :
260 : /**
261 : * This method pop the attribute token
262 : * @update harishd 03/25/99
263 : * @return token at anIndex
264 : */
265 :
266 : CToken*
267 0 : nsCParserNode::PopAttributeToken() {
268 0 : return 0;
269 : }
270 :
271 : CToken*
272 0 : nsCParserNode::PopAttributeTokenFront() {
273 0 : return 0;
274 : }
275 :
276 : /** Retrieve a string containing the tag and its attributes in "source" form
277 : * @update rickg 06June2000
278 : * @return void
279 : */
280 : void
281 0 : nsCParserNode::GetSource(nsString& aString) const
282 : {
283 0 : eHTMLTags theTag = mToken ? (eHTMLTags)mToken->GetTypeID() : eHTMLTag_unknown;
284 0 : aString.Assign(PRUnichar('<'));
285 0 : const PRUnichar* theTagName = nsHTMLTags::GetStringValue(theTag);
286 0 : if(theTagName) {
287 0 : aString.Append(theTagName);
288 : }
289 0 : aString.Append(PRUnichar('>'));
290 0 : }
291 :
292 : /** Release all the objects you're holding to.
293 : * @update harishd 08/02/00
294 : * @return void
295 : */
296 : nsresult
297 1967 : nsCParserNode::ReleaseAll()
298 : {
299 1967 : if(mTokenAllocator) {
300 1967 : IF_FREE(mToken,mTokenAllocator);
301 : }
302 1967 : return NS_OK;
303 : }
304 :
305 : nsresult
306 0 : nsCParserStartNode::Init(CToken* aToken,
307 : nsTokenAllocator* aTokenAllocator,
308 : nsNodeAllocator* aNodeAllocator)
309 : {
310 0 : NS_ASSERTION(mAttributes.GetSize() == 0, "attributes not recycled!");
311 0 : return nsCParserNode::Init(aToken, aTokenAllocator, aNodeAllocator);
312 : }
313 :
314 732 : void nsCParserStartNode::AddAttribute(CToken* aToken)
315 : {
316 732 : NS_ASSERTION(0 != aToken, "Error: Token shouldn't be null!");
317 732 : mAttributes.Push(aToken);
318 732 : }
319 :
320 : PRInt32
321 233 : nsCParserStartNode::GetAttributeCount(bool askToken) const
322 : {
323 233 : PRInt32 result = 0;
324 233 : if (askToken) {
325 0 : result = mToken ? mToken->GetAttributeCount() : 0;
326 : }
327 : else {
328 233 : result = mAttributes.GetSize();
329 : }
330 233 : return result;
331 : }
332 :
333 : const nsAString&
334 1067 : nsCParserStartNode::GetKeyAt(PRUint32 anIndex) const
335 : {
336 1067 : if ((PRInt32)anIndex < mAttributes.GetSize()) {
337 : CAttributeToken* attr =
338 1067 : static_cast<CAttributeToken*>(mAttributes.ObjectAt(anIndex));
339 1067 : if (attr) {
340 1067 : return attr->GetKey();
341 : }
342 : }
343 0 : return EmptyString();
344 : }
345 :
346 : const nsAString&
347 621 : nsCParserStartNode::GetValueAt(PRUint32 anIndex) const
348 : {
349 621 : if (PRInt32(anIndex) < mAttributes.GetSize()) {
350 : CAttributeToken* attr =
351 621 : static_cast<CAttributeToken*>(mAttributes.ObjectAt(anIndex));
352 621 : if (attr) {
353 621 : return attr->GetValue();
354 : }
355 : }
356 0 : return EmptyString();
357 : }
358 :
359 : CToken*
360 0 : nsCParserStartNode::PopAttributeToken()
361 : {
362 0 : return static_cast<CToken*>(mAttributes.Pop());
363 : }
364 :
365 : CToken*
366 0 : nsCParserStartNode::PopAttributeTokenFront()
367 : {
368 0 : return static_cast<CToken*>(mAttributes.PopFront());
369 : }
370 :
371 0 : void nsCParserStartNode::GetSource(nsString& aString) const
372 : {
373 0 : aString.Assign(PRUnichar('<'));
374 : const PRUnichar* theTagName =
375 0 : nsHTMLTags::GetStringValue(nsHTMLTag(mToken->GetTypeID()));
376 0 : if (theTagName) {
377 0 : aString.Append(theTagName);
378 : }
379 : PRInt32 index;
380 0 : PRInt32 size = mAttributes.GetSize();
381 0 : for (index = 0 ; index < size; ++index) {
382 : CAttributeToken *theToken =
383 0 : static_cast<CAttributeToken*>(mAttributes.ObjectAt(index));
384 0 : if (theToken) {
385 0 : theToken->AppendSourceTo(aString);
386 0 : aString.Append(PRUnichar(' ')); //this will get removed...
387 : }
388 : }
389 0 : aString.Append(PRUnichar('>'));
390 0 : }
391 :
392 0 : nsresult nsCParserStartNode::ReleaseAll()
393 : {
394 0 : NS_ASSERTION(0!=mTokenAllocator, "Error: no token allocator");
395 : CToken* theAttrToken;
396 0 : while ((theAttrToken = static_cast<CToken*>(mAttributes.Pop()))) {
397 0 : IF_FREE(theAttrToken, mTokenAllocator);
398 : }
399 0 : nsCParserNode::ReleaseAll();
400 0 : return NS_OK;
401 : }
402 :
|