Xalan-C++ API Reference  1.12.0
VariablesStack.hpp
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 #if !defined(XALAN_VARIABLESSTACK_HEADER_GUARD)
19 #define XALAN_VARIABLESSTACK_HEADER_GUARD
20 
21 
22 
23 // Base include file. Must be first.
25 
26 
27 
28 #include <cassert>
29 
30 
31 
33 
34 
35 
37 #include <xalanc/XPath/XObject.hpp>
38 
39 
40 
42 
43 
44 
45 namespace XALAN_CPP_NAMESPACE {
46 
47 
48 
49 class Arg;
50 class ElemTemplateElement;
51 class ElemVariable;
52 class StylesheetExecutionContext;
53 class XalanNode;
54 
55 
56 
57 /**
58  * Defines a class to keep track of a stack for macro arguments.
59  */
61 {
62 public:
63 
64  typedef unsigned long size_type;
65 
66  /**
67  * Constructor for a variable stack.
68  */
69  explicit
70  VariablesStack(MemoryManager& theManager);
71 
72  ~VariablesStack();
73 
74  /**
75  * Reset the stack.
76  */
77  void
78  reset();
79 
80  /**
81  * Push a frame marker for an element.
82  *
83  * @param elem the element
84  */
85  void
86  pushElementFrame(const ElemTemplateElement* elem);
87 
88  /**
89  * Pop a frame marker for an element.
90  *
91  * @param elem the element
92  */
93  void
94  popElementFrame();
95 
96  /**
97  * Push a context marker onto the stack to let us know when to stop
98  * searching for a var.
99  *
100  * @param caller caller node
101  * @param sourceNode source node
102  */
103  void
104  pushContextMarker();
105 
106  /**
107  * Pop the current context from the current context stack.
108  */
109  void
110  popContextMarker();
111 
113  {
115  m_qname(0),
116  m_value(),
117  m_variable(0)
118  {
119  }
120 
122  const XalanQName* qname,
123  const XObjectPtr value) :
124  m_qname(qname),
125  m_value(value),
126  m_variable(0)
127  {
128  }
129 
131  const XalanQName* qname,
132  const ElemVariable* variable) :
133  m_qname(qname),
134  m_value(),
135  m_variable(variable)
136  {
137  }
138 
140 
142 
144  };
145 
149 
150  /**
151  * Push the provided objects as parameters. You must call
152  * popContextMarker() when you are done with the arguments.
153  *
154  * @param theParam The vector containing the parameters.
155  */
156  void
157  pushParams(const ParamsVectorType& theParams);
158 
159  /**
160  * Given a name, return a string representing the value, but don't look
161  * in the global space. Since the variable may not yet have been
162  * evaluated, this may return a null XObjectPtr.
163  *
164  * @param theName name of variable
165  * @param exeuctionContext the current execution context
166  * @param fNameFound set to true if the name was found, false if not.
167  * @return pointer to XObject for variable
168  */
169  const XObjectPtr
171  const XalanQName& qname,
172  StylesheetExecutionContext& executionContext,
173  bool& fNameFound)
174  {
175  return findXObject(qname, executionContext, true, false, fNameFound);
176  }
177 
178  /**
179  * Given a name, find the corresponding XObject. If the variable
180  * exists, but has not yet been evaluated, the variable will be
181  * evaluated and the result returned. This may return a null XObjectPtr,
182  * if the variable was not found.
183  *
184  * @param qname name of variable
185  * @param exeuctionContext the current execution context
186  * @param fNameFound set to true if the name was found, false if not.
187  * @return pointer to the corresponding XObject
188  */
189  const XObjectPtr
191  const XalanQName& qname,
192  StylesheetExecutionContext& executionContext,
193  bool& fNameFound)
194  {
195  return findXObject(qname, executionContext, false, true, fNameFound);
196  }
197 
198  /**
199  * Push a named variable onto the processor variable stack. Don't forget
200  * to call startContext before pushing a series of arguments for a given
201  * template.
202  *
203  * @param name name of variable
204  * @param val pointer to ElemVariable
205  * @param e element marker for variable
206  */
207  void
208  pushVariable(
209  const XalanQName& name,
210  const ElemVariable* var,
211  const ElemTemplateElement* e);
212 
213  /**
214  * Push a named variable onto the processor variable stack. Don't forget
215  * to call startContext before pushing a series of arguments for a given
216  * template.
217  *
218  * @param name name of variable
219  * @param val pointer to XObject value
220  * @param e element marker for variable
221  */
222  void
223  pushVariable(
224  const XalanQName& name,
225  const XObjectPtr& val,
226  const ElemTemplateElement* e);
227 
228  /**
229  * Mark the top of the stack.
230  */
231  void
232  start();
233 
234  /**
235  * Reset all params in the current stack frame.
236  */
237  void
238  resetParams();
239 
240  /**
241  * Mark the top of the global stack frame.
242  */
243  void
244  markGlobalStackFrame();
245 
246  /**
247  * Clear the marking of the global stack frame.
248  */
249  void
250  unmarkGlobalStackFrame();
251 
252  /**
253  * Set the top of the stack frame from where a search for a variable or
254  * param should take place. Calling with no parameter will cause the
255  * index to be set to the size of the stack.
256  *
257  * @param currentStackFrameIndex new value of index
258  */
259  void
260  setCurrentStackFrameIndex(size_type currentStackFrameIndex = ~0u)
261  {
262  if (currentStackFrameIndex == ~0u)
263  {
264  assert(size_type(m_stack.size()) == m_stack.size());
265 
266  m_currentStackFrameIndex = size_type(m_stack.size());
267  }
268  else
269  {
270  m_currentStackFrameIndex = currentStackFrameIndex;
271  }
272  }
273 
274  /**
275  * Get the top of the stack frame from where a search
276  * for a variable or param should take place.
277  *
278  * @return current value of index
279  */
280  size_type
282  {
283  return m_currentStackFrameIndex;
284  }
285 
286  /**
287  * Get the top of the global stack frame.
288  *
289  * @return current value of index
290  */
291  size_type
293  {
294  return m_globalStackFrameIndex;
295  }
296 
298  {
299  public:
300 
302 
303  virtual
305 
306 
307  virtual const XalanDOMChar*
308  getType() const
309  {
310  return m_type;
311  }
312 
313  private:
314 
315  static const XalanDOMChar m_type[];
316 
317  };
318 
320  {
321  public:
322 
323  PushParamFunctor(VariablesStack& theVariablesStack) :
324  m_variablesStack(theVariablesStack)
325  {
326  }
327 
328  void
329  operator()(const ParamsVectorType::value_type& theEntry) const;
330 
331  private:
332 
333  VariablesStack& m_variablesStack;
334  };
335 
337  {
338  public:
339 
340  /**
341  * Enumeration for types of stack entries, one of context state, context
342  * marker, element marker, or argument.
343  */
344  enum eType { eContextMarker,
349  eNextValue };
350 
351  /**
352  * Construct a context marker.
353  */
354  explicit
355  StackEntry();
356 
357  /**
358  * Construct a variable that is already evaluated.
359  */
360  StackEntry(
361  const XalanQName* name,
362  const XObjectPtr& val,
363  bool isParam = false);
364 
365  /**
366  * Construct a variable that has not been evaluated yet.
367  */
368  StackEntry(
369  const XalanQName* name,
370  const ElemVariable* var,
371  bool isParam = false);
372 
373  /**
374  * Construct an element frame marker.
375  */
376  StackEntry(const ElemTemplateElement* elem);
377 
378 
379  /**
380  * Copy constructor...
381  */
382  StackEntry(const StackEntry& theSource);
383 
384  /**
385  * Destructor...
386  */
387  ~StackEntry();
388 
389  /**
390  * Determine type of stack entry
391  *
392  * @return enumeration value for type
393  */
394  eType
395  getType() const
396  {
397  return m_type;
398  }
399 
400  /**
401  * Retrieve object name. Valid only for variables
402  *
403  * @return qualified name of object
404  */
405  const XalanQName*
406  getName() const
407  {
408  return m_qname;
409  }
410 
411  /**
412  * Retrieve object's XObject pointer. Valid only for variables
413  *
414  * @return pointer to XObject
415  */
416  const XObjectPtr&
417  getValue() const
418  {
419  return m_value;
420  }
421 
422  /**
423  * Retrieve object's XObject pointer. Valid only for variables
424  *
425  * @return pointer to XObject
426  */
427  void
428  setValue(const XObjectPtr& theValue)
429  {
430  m_value = theValue;
431  }
432 
433  /**
434  * Retrieve object's XObject pointer. Valid only for variables
435  *
436  * @return pointer to XObject
437  */
438  const ElemVariable*
439  getVariable() const
440  {
441  return m_variable;
442  }
443 
444  void
445  activate();
446 
447  void
448  deactivate();
449 
450  /**
451  * Retrieve the ElemTemplateElem where frame begins. Valid only for element frame markers
452  *
453  * @return ElemTemplateElement corresponding to marker
454  */
455  const ElemTemplateElement*
456  getElement() const
457  {
458  return m_element;
459  }
460 
461  StackEntry&
462  operator=(const StackEntry& theRHS);
463 
464  bool
465  operator==(const StackEntry& theRHS) const;
466 
467  private:
468 
469  // Data members...
470  eType m_type;
471 
472  const XalanQName* m_qname;
473 
474  XObjectPtr m_value;
475 
476  const ElemVariable* m_variable;
477 
478  const ElemTemplateElement* m_element;
479  };
480 
482 
483  size_type
484  getStackSize() const
485  {
486  return size_type(m_stack.size());
487  }
488 
489  enum { eDefaultStackSize = 100 };
490 
491 private:
492 
493  class CommitPushParams
494  {
495  public:
496 
497  CommitPushParams(VariablesStack& theVariablesStack);
498 
499  ~CommitPushParams();
500 
501  void
502  commit()
503  {
504  m_variablesStack = 0;
505  }
506 
507  private:
508 
509  VariablesStack* m_variablesStack;
510 
511  size_type m_stackSize;
512  };
513 
514  friend class CommitPushParams;
515 
516  /**
517  * Check to see if an element frame for the particular element has already
518  * been pushed.
519  *
520  * @param elem element in question
521  * @return true if it has been pushed already
522  */
523  bool
524  elementFrameAlreadyPushed(const ElemTemplateElement* elem) const;
525 
526  /**
527  * Push an entry onto the stack.
528  *
529  * @param stack entry to push
530  */
531  void
532  push(const StackEntry& theEntry);
533 
534  /**
535  * Pop an entry from the top of the stack.
536  */
537  void
538  pop();
539 
540  /**
541  * Get a reference to the entry at the back (top) of the stack.
542  *
543  * @return a reference to the back of the stack.
544  */
545  const StackEntry&
546  back() const
547  {
548  assert(m_stack.empty() == false);
549 
550  return m_stack.back();
551  }
552 
553  friend class CommitPushElementFrame;
554  friend class EnsurePop;
555  friend class PushParamFunctor;
556  friend class SetAndRestoreForceGlobalSearch;
557 
558  const XObjectPtr
559  findXObject(
560  const XalanQName& name,
561  StylesheetExecutionContext& executionContext,
562  bool fIsParam,
563  bool fSearchGlobalSpace,
564  bool& fNameFound);
565 
566  size_type
567  findEntry(
568  const XalanQName& name,
569  bool fIsParam,
570  bool fSearchGlobalSpace);
571 
572 
573  VariableStackStackType m_stack;
574 
575  size_type m_globalStackFrameIndex;
576 
577  bool m_globalStackFrameMarked;
578 
579  /**
580  * This is the top of the stack frame from where a search
581  * for a variable or param should take place. It may not
582  * be the real stack top.
583  */
584  size_type m_currentStackFrameIndex;
585 
586  /**
587  * This will be a stack for any variable definitions
588  * that are being evaluated dynamically, to protect
589  * against circular definitions.
590  */
591  RecursionGuardStackType m_guardStack;
592 
593  /**
594  * This will be a stack for tracking element frames.
595  * This is only used in debug builds.
596  */
597  ElemTemplateElementStackType m_elementFrameStack;
598 };
599 
600 
601 
602 }
603 
604 
605 
606 #endif // #if !defined(XALAN_VARIABLESSTACK_HEADER_GUARD)
xalanc::VariablesStack::ParamsVectorType
XalanVector< ParamsVectorEntry > ParamsVectorType
Definition: VariablesStack.hpp:146
xalanc::VariablesStack::VariableStackStackType
XalanVector< StackEntry > VariableStackStackType
Definition: VariablesStack.hpp:481
XALAN_CPP_NAMESPACE
#define XALAN_CPP_NAMESPACE
Xalan-C++ namespace, including major and minor version.
Definition: XalanVersion.hpp:76
xalanc::VariablesStack::ParamsVectorEntry::m_variable
const ElemVariable * m_variable
Definition: VariablesStack.hpp:143
xalanc::VariablesStack::StackEntry::getName
const XalanQName * getName() const
Retrieve object name.
Definition: VariablesStack.hpp:406
xalanc::VariablesStack
Defines a class to keep track of a stack for macro arguments.
Definition: VariablesStack.hpp:60
xalanc::StylesheetExecutionContext
Definition: StylesheetExecutionContext.hpp:106
xalanc::VariablesStack::ParamsVectorEntry::m_value
XObjectPtr m_value
Definition: VariablesStack.hpp:141
xalanc::VariablesStack::InvalidStackContextException::getType
virtual const XalanDOMChar * getType() const
Retrieve type of exception.
Definition: VariablesStack.hpp:308
xalanc::XalanVector
Definition: XalanVector.hpp:58
xalanc::VariablesStack::ParamsVectorEntry::m_qname
const XalanQName * m_qname
Definition: VariablesStack.hpp:139
xalanc::VariablesStack::getStackSize
size_type getStackSize() const
Definition: VariablesStack.hpp:484
xalanc::VariablesStack::ElemTemplateElementStackType
XalanVector< const ElemTemplateElement * > ElemTemplateElementStackType
Definition: VariablesStack.hpp:148
XALAN_XSLT_EXPORT
#define XALAN_XSLT_EXPORT
Definition: XSLTDefinitions.hpp:27
xalanc::size_type
size_t size_type
Definition: XalanMap.hpp:46
xalanc::ElemTemplateElement
Definition: ElemTemplateElement.hpp:79
xalanc::VariablesStack::RecursionGuardStackType
XalanVector< const ElemVariable * > RecursionGuardStackType
Definition: VariablesStack.hpp:147
XalanVector.hpp
xalanc::VariablesStack::StackEntry::setValue
void setValue(const XObjectPtr &theValue)
Retrieve object's XObject pointer.
Definition: VariablesStack.hpp:428
xalanc::operator==
bool operator==(const XalanVector< Type > &theLHS, const XalanVector< Type > &theRHS)
Definition: XalanVector.hpp:1118
xalanc::VariablesStack::InvalidStackContextException
Definition: VariablesStack.hpp:297
xalanc::VariablesStack::StackEntry::eVariable
@ eVariable
Definition: VariablesStack.hpp:345
XSLTProcessorException.hpp
xalanc::VariablesStack::PushParamFunctor
Definition: VariablesStack.hpp:319
XalanQName.hpp
xalanc::VariablesStack::ParamsVectorEntry::ParamsVectorEntry
ParamsVectorEntry()
Definition: VariablesStack.hpp:114
xalanc::XObjectPtr
Class to hold XObjectPtr return types.
Definition: XObject.hpp:883
xalanc::VariablesStack::StackEntry::getValue
const XObjectPtr & getValue() const
Retrieve object's XObject pointer.
Definition: VariablesStack.hpp:417
xalanc::VariablesStack::StackEntry::getVariable
const ElemVariable * getVariable() const
Retrieve object's XObject pointer.
Definition: VariablesStack.hpp:439
xalanc::VariablesStack::StackEntry
Definition: VariablesStack.hpp:336
xalanc::VariablesStack::StackEntry::eType
eType
Enumeration for types of stack entries, one of context state, context marker, element marker,...
Definition: VariablesStack.hpp:344
xalanc::VariablesStack::StackEntry::getType
eType getType() const
Determine type of stack entry.
Definition: VariablesStack.hpp:395
xalanc::VariablesStack::StackEntry::getElement
const ElemTemplateElement * getElement() const
Retrieve the ElemTemplateElem where frame begins.
Definition: VariablesStack.hpp:456
xalanc::VariablesStack::ParamsVectorEntry
Definition: VariablesStack.hpp:112
xalanc::VariablesStack::StackEntry::eActiveParam
@ eActiveParam
Definition: VariablesStack.hpp:347
xalanc::ElemVariable
Definition: ElemVariable.hpp:47
xalanc::VariablesStack::getCurrentStackFrameIndex
size_type getCurrentStackFrameIndex() const
Get the top of the stack frame from where a search for a variable or param should take place.
Definition: VariablesStack.hpp:281
xalanc::VariablesStack::ParamsVectorEntry::ParamsVectorEntry
ParamsVectorEntry(const XalanQName *qname, const ElemVariable *variable)
Definition: VariablesStack.hpp:130
xalanc::VariablesStack::StackEntry::eElementFrameMarker
@ eElementFrameMarker
Definition: VariablesStack.hpp:348
xalanc::VariablesStack::size_type
unsigned long size_type
Definition: VariablesStack.hpp:64
xalanc::XSLTProcessorException
Definition: XSLTProcessorException.hpp:37
xalanc::VariablesStack::setCurrentStackFrameIndex
void setCurrentStackFrameIndex(size_type currentStackFrameIndex=~0u)
Set the top of the stack frame from where a search for a variable or param should take place.
Definition: VariablesStack.hpp:260
XSLTDefinitions.hpp
xalanc::VariablesStack::StackEntry::eParam
@ eParam
Definition: VariablesStack.hpp:346
xalanc::XalanQName
Class to represent a qualified name.
Definition: XalanQName.hpp:70
xalanc::XalanVector::value_type
Type value_type
Definition: XalanVector.hpp:63
xalanc::VariablesStack::getVariable
const XObjectPtr getVariable(const XalanQName &qname, StylesheetExecutionContext &executionContext, bool &fNameFound)
Given a name, find the corresponding XObject.
Definition: VariablesStack.hpp:190
xalanc::VariablesStack::getParamVariable
const XObjectPtr getParamVariable(const XalanQName &qname, StylesheetExecutionContext &executionContext, bool &fNameFound)
Given a name, return a string representing the value, but don't look in the global space.
Definition: VariablesStack.hpp:170
xalanc::XalanDOMString
Definition: XalanDOMString.hpp:45
xalanc::VariablesStack::getGlobalStackFrameIndex
size_type getGlobalStackFrameIndex() const
Get the top of the global stack frame.
Definition: VariablesStack.hpp:292
xalanc::VariablesStack::ParamsVectorEntry::ParamsVectorEntry
ParamsVectorEntry(const XalanQName *qname, const XObjectPtr value)
Definition: VariablesStack.hpp:121
XObject.hpp
xalanc::VariablesStack::PushParamFunctor::PushParamFunctor
PushParamFunctor(VariablesStack &theVariablesStack)
Definition: VariablesStack.hpp:323