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 
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
87 
88  /**
89  * Pop a frame marker for an element.
90  *
91  * @param elem the element
92  */
93  void
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
105 
106  /**
107  * Pop the current context from the current context stack.
108  */
109  void
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
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
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
239 
240  /**
241  * Mark the top of the global stack frame.
242  */
243  void
245 
246  /**
247  * Clear the marking of the global stack frame.
248  */
249  void
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  */
349  eNextValue };
350 
351  /**
352  * Construct a context marker.
353  */
354  explicit
356 
357  /**
358  * Construct a variable that is already evaluated.
359  */
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  */
369  const XalanQName* name,
370  const ElemVariable* var,
371  bool isParam = false);
372 
373  /**
374  * Construct an element frame marker.
375  */
377 
378 
379  /**
380  * Copy constructor...
381  */
382  StackEntry(const StackEntry& theSource);
383 
384  /**
385  * Destructor...
386  */
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
446 
447  void
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)
#define XALAN_XSLT_EXPORT
#define XALAN_CPP_NAMESPACE
Xalan-C++ namespace, including major and minor version.
InvalidStackContextException(XalanDOMString &theResult)
virtual const XalanDOMChar * getType() const
Retrieve type of exception.
void operator()(const ParamsVectorType::value_type &theEntry) const
PushParamFunctor(VariablesStack &theVariablesStack)
const ElemTemplateElement * getElement() const
Retrieve the ElemTemplateElem where frame begins.
eType getType() const
Determine type of stack entry.
const XalanQName * getName() const
Retrieve object name.
void setValue(const XObjectPtr &theValue)
Retrieve object's XObject pointer.
const ElemVariable * getVariable() const
Retrieve object's XObject pointer.
StackEntry(const StackEntry &theSource)
Copy constructor...
StackEntry(const XalanQName *name, const XObjectPtr &val, bool isParam=false)
Construct a variable that is already evaluated.
eType
Enumeration for types of stack entries, one of context state, context marker, element marker,...
StackEntry()
Construct a context marker.
StackEntry(const ElemTemplateElement *elem)
Construct an element frame marker.
StackEntry(const XalanQName *name, const ElemVariable *var, bool isParam=false)
Construct a variable that has not been evaluated yet.
const XObjectPtr & getValue() const
Retrieve object's XObject pointer.
bool operator==(const StackEntry &theRHS) const
StackEntry & operator=(const StackEntry &theRHS)
Defines a class to keep track of a stack for macro arguments.
XalanVector< const ElemTemplateElement * > ElemTemplateElementStackType
XalanVector< ParamsVectorEntry > ParamsVectorType
XalanVector< StackEntry > VariableStackStackType
void pushVariable(const XalanQName &name, const ElemVariable *var, const ElemTemplateElement *e)
Push a named variable onto the processor variable stack.
void pushParams(const ParamsVectorType &theParams)
Push the provided objects as parameters.
void popElementFrame()
Pop a frame marker for an element.
size_type getGlobalStackFrameIndex() const
Get the top of the global stack frame.
void pushContextMarker()
Push a context marker onto the stack to let us know when to stop searching for a var.
void pushElementFrame(const ElemTemplateElement *elem)
Push a frame marker for an element.
void unmarkGlobalStackFrame()
Clear the marking of the global stack frame.
void start()
Mark the top of the stack.
void popContextMarker()
Pop the current context from the current context stack.
const XObjectPtr getVariable(const XalanQName &qname, StylesheetExecutionContext &executionContext, bool &fNameFound)
Given a name, find the corresponding XObject.
VariablesStack(MemoryManager &theManager)
Constructor for a variable stack.
void pushVariable(const XalanQName &name, const XObjectPtr &val, const ElemTemplateElement *e)
Push a named variable onto the processor variable stack.
size_type getCurrentStackFrameIndex() const
Get the top of the stack frame from where a search for a variable or param should take place.
void markGlobalStackFrame()
Mark the top of the global stack frame.
size_type getStackSize() const
XalanVector< const ElemVariable * > RecursionGuardStackType
void reset()
Reset the stack.
void resetParams()
Reset all params in the current stack frame.
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.
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.
Class to hold XObjectPtr return types.
Definition: XObject.hpp:884
Class to represent a qualified name.
Definition: XalanQName.hpp:71
size_t size_type
Definition: XalanMap.hpp:46
ParamsVectorEntry(const XalanQName *qname, const ElemVariable *variable)
ParamsVectorEntry(const XalanQName *qname, const XObjectPtr value)