File: ProcessContext.h

package info (click to toggle)
openjade 1.4devel1-20.1
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 6,636 kB
  • sloc: cpp: 90,082; sh: 10,847; ansic: 2,365; lisp: 894; perl: 604; makefile: 443; sed: 93
file content (259 lines) | stat: -rw-r--r-- 6,972 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
// Copyright (c) 1996 James Clark
// See the file copying.txt for copying permission.

#ifndef ProcessContext_INCLUDED
#define ProcessContext_INCLUDED 1

#include <OpenSP/Resource.h>
#include <OpenSP/Ptr.h>
#include <OpenSP/Vector.h>
#include <OpenSP/NCVector.h>
#include <OpenSP/Owner.h>
#include "Collector.h"
#include "Style.h"
#include "FOTBuilder.h"
#include "ELObj.h"
#include "SosofoObj.h"
#include "VM.h"
#include "ProcessingMode.h"
#include <OpenSP/Link.h>
#include <OpenSP/IList.h>
#include <OpenSP/IQueue.h>

#ifdef DSSSL_NAMESPACE
namespace DSSSL_NAMESPACE {
#endif

class Expression;

class ProcessContext : public Collector::DynamicRoot {
public:
  ProcessContext(Interpreter &, FOTBuilder &);
  ~ProcessContext();
  FOTBuilder &currentFOTBuilder();
  StyleStack &currentStyleStack();
  void process(const NodePtr &);
  void processNode(const NodePtr &, const ProcessingMode *,
		   const Location &, bool chunk = 1);
  void processNodeSafe(const NodePtr &, const ProcessingMode *,
		       const Location &, bool chunk = 1);
  void nextMatch(StyleObj *, const Location &loc);
  void processChildren(const ProcessingMode *, const Location &);
  void processChildrenTrim(const ProcessingMode *, const Location &);
  void characters(const Char *, size_t, const Location &);
  void charactersFromNode(const NodePtr &, const Char *, size_t,
			  const Location &);
  void trace(Collector &) const;
  void startFlowObj();
  void endFlowObj();
  // Uses of label: do this
  void startConnection(SymbolObj *, const Location &);
  void endConnection();

  // Contains information about which flow object classes a port shall accept
  // and can validate flow objects according to this information.
  class Validator : public Resource {
  public:
    // If the flow object specified by the argument is valid in the current
    // position in this stream, this function returns true and updates
    // state information as if the flow object was added to the stream.
    // If the FO isn't valid, this method reports it with a message.
    // Default implementation returns true.
    virtual bool isValid(const FlowObj &, ProcessContext &);
    virtual bool charsValid(size_t, const Location &, ProcessContext &);
  };

  void validate(const FlowObj &);
  void endValidate();
  // happens only for object with a non-principal port
  void pushPorts(bool hasPrincipalPort,
		 const Vector<SymbolObj *> &ports,
		 const Vector<FOTBuilder *> &fotbs,
		 const Vector<Validator *> validators,
		 Validator *principalPortValidator = 0);
  void popPorts();
  void pushPrincipalPort(Validator *);
  void popPrincipalPort();
  // Used by SpS headers and footers.
  void pushPseudoPort(FOTBuilder *principalPort,
			 Validator *);
  void popPseudoPort();
  // happens inside pushPorts() (if any)
  void startMapContent(ELObj *, const Location &);
  void endMapContent();
  void startDiscardLabeled(SymbolObj *);
  void endDiscardLabeled();
  // table support
  void startTable();
  void endTable();
  void startTablePart();
  void endTablePart();
  void addTableColumn(unsigned columnIndex, unsigned span, StyleObj *);
  unsigned currentTableColumn();
  void noteTableCell(unsigned colIndex, unsigned colSpan, unsigned rowSpan);
  StyleObj *tableColumnStyle(unsigned columnIndex, unsigned span);
  StyleObj *tableRowStyle();
  void startTableRow(StyleObj *);
  bool inTable() const;
  bool inTableRow();
  void endTableRow();
  void clearPageType();
  void setPageType(unsigned);
  bool getPageType(unsigned &) const;
  void startParagraph();
  void endParagraph();
  bool paragraphAncestor() const;

  VM &vm();
 private:
  ProcessContext(const ProcessContext &); // undefined
  void operator=(const ProcessContext &); // undefined
  void badContentMap(bool &, const Location &);
  void coverSpannedRows();
  void restoreConnection(unsigned connectableLevel, size_t portIndex);
  struct Port {
    Port();
    FOTBuilder *fotb;
    IQueue<NodeSaveFOTBuilder> saveQueue;
    Vector<SymbolObj *> labels;
    Ptr<Validator> validator;
    unsigned connected;
  };
  // A flow object with a port that can be connected to.
  struct Connectable;
  friend struct Connectable;
  struct Connectable : public Link {
    Connectable(int nPorts, const StyleStack &, unsigned);
    NCVector<Port> ports;
    StyleStack styleStack;
    unsigned flowObjLevel;
    Vector<SymbolObj *> principalPortLabels;
    Ptr<Validator> principalPortValidator;
  };
  // A connection between a flow object and its flow parent
  // made with label:.
  struct Connection;
  friend struct Connection;
  struct Connection : public Link {
    Connection(FOTBuilder *, const StyleStack & = StyleStack());
    Connection(const StyleStack &, Port *, unsigned connectableLevel);
    FOTBuilder *fotb;
    StyleStack styleStack;
    Port *port;
    unsigned connectableLevel;
    unsigned nBadFollow;
  };
  struct Table : public Link {
    Table();
    unsigned currentColumn;
    // first index is column (zero-based)
    // second is span - 1.
    Vector<Vector<StyleObj *> > columnStyles;
    // for each column, how many rows are covered
    // starting with the current row
    Vector<unsigned> covered;
    unsigned nColumns;
    StyleObj *rowStyle;
    bool inTableRow;
    unsigned rowConnectableLevel;
  };
  struct NodeStackEntry {
    unsigned long elementIndex;
    unsigned groveIndex;
    const ProcessingMode *processingMode;
  };
  FOTBuilder ignoreFotb_;
  IList<Connection> connectionStack_;
  IList<Connectable> connectableStack_;
  unsigned connectableStackLevel_;
  IList<Table> tableStack_;
  NCVector<IQueue<NodeSaveFOTBuilder> > principalPortSaveQueues_;
  VM vm_;
  ProcessingMode::Specificity matchSpecificity_;
  unsigned flowObjLevel_;
  bool havePageType_;
  unsigned pageType_;
  unsigned paragraphLevel_;
  Vector<NodeStackEntry> nodeStack_;
  Vector<unsigned> invalidLevels_;
  Vector<Ptr<Validator> > validatorStack_;
  friend class CurrentNodeSetter;
  friend struct Table;
};

inline
FOTBuilder &ProcessContext::currentFOTBuilder()
{
  return *connectionStack_.head()->fotb;
}

inline
StyleStack &ProcessContext::currentStyleStack()
{
  return connectionStack_.head()->styleStack;
}

inline
VM &ProcessContext::vm()
{
  return vm_;
}

inline
void ProcessContext::startFlowObj()
{
  flowObjLevel_++;
}

inline
void ProcessContext::setPageType(unsigned n)
{
  havePageType_ = 1;
  pageType_ = n;
}

inline
void ProcessContext::clearPageType()
{
  havePageType_ = 0;
}

inline
bool ProcessContext::getPageType(unsigned &n) const
{
  if (!havePageType_)
    return 0;
  n = pageType_;
  return 1;
}

inline
bool ProcessContext::inTable() const
{
  return !tableStack_.empty();
}

inline
void ProcessContext::startParagraph()
{
  paragraphLevel_++;
}

inline
void ProcessContext::endParagraph()
{
  paragraphLevel_--;
}

inline
bool ProcessContext::paragraphAncestor() const
{
  return paragraphLevel_ > 0;
}

#ifdef DSSSL_NAMESPACE
}
#endif

#endif /* not ProcessContext_INCLUDED */