1 // Copyright (c) 1994 James Clark
2 // See the file COPYING for copying permission.
3 #pragma ident "%Z%%M% %I% %E% SMI"
4
5 #ifndef Lpd_INCLUDED
6 #define Lpd_INCLUDED 1
7 #ifdef __GNUG__
8 #pragma interface
9 #endif
10
11 #include "Attribute.h"
12 #include "StringC.h"
13 #include "Ptr.h"
14 #include "Resource.h"
15 #include "Boolean.h"
16 #include "Named.h"
17 #include "NamedTable.h"
18 #include "Syntax.h"
19 #include "Location.h"
20 #include "Dtd.h"
21
22 #ifdef SP_NAMESPACE
23 namespace SP_NAMESPACE {
24 #endif
25
26 class ElementType;
27
28 struct SP_API ResultElementSpec {
29 ResultElementSpec();
30 const ElementType *elementType;
31 AttributeList attributeList;
32 void swap(ResultElementSpec &);
33 };
34
35 class SP_API Lpd : public Resource {
36 public:
37 enum Type { simpleLink, implicitLink, explicitLink };
38 Lpd(const StringC &, Type, const Location &,
39 const Ptr<Dtd> &sourceDtd);
40 virtual ~Lpd();
41 Type type() const;
42 const Location &location() const;
43 const Ptr<Dtd> &sourceDtd();
44 ConstPtr<Dtd> sourceDtd() const;
45 Boolean active() const;
46 void activate();
47 const ConstPtr<StringResource<Char> > &namePointer() const;
48 const StringC &name() const;
49 private:
50 Lpd(const Lpd &); // undefined
51 void operator=(const Lpd &); // undefined
52 Type type_;
53 Location location_;
54 Boolean active_;
55 Ptr<Dtd> sourceDtd_;
56 ConstPtr<StringResource<Char> > name_;
57 };
58
59 class SP_API SimpleLpd : public Lpd, public Attributed {
60 public:
61 SimpleLpd(const StringC &, const Location &,
62 const Ptr<Dtd> &sourceDtd);
63 private:
64 SimpleLpd(const SimpleLpd &); // undefined
65 void operator=(const SimpleLpd &); // undefined
66 };
67
68 class LinkSet;
69
70 // A link rule whose source element specification is not implied.
71
72 class SP_API SourceLinkRule {
73 public:
74 SourceLinkRule();
75 void setLinkAttributes(AttributeList &);
76 void setResult(const ElementType *, AttributeList &);
77 void setUselink(const LinkSet *);
78 void setPostlink(const LinkSet *);
79 void setPostlinkRestore();
80 void swap(SourceLinkRule &);
81 const AttributeList &attributes() const;
82 const ResultElementSpec &resultElementSpec() const;
83 const LinkSet *uselink() const;
84 const LinkSet *postlink() const;
85 Boolean postlinkRestore() const;
86 private:
87 const LinkSet *uselink_;
88 const LinkSet *postlink_;
89 Boolean postlinkRestore_;
90 AttributeList linkAttributes_;
91 ResultElementSpec resultElementSpec_;
92 };
93
94 class SP_API SourceLinkRuleResource : public Resource, public SourceLinkRule {
95 public:
96 SourceLinkRuleResource();
97 };
98
99 class SP_API LinkSet : public Named {
100 public:
101 LinkSet(const StringC &, const Dtd *);
102 void setDefined();
103 Boolean defined() const;
104 void addImplied(const ElementType *, AttributeList &);
105 size_t nLinkRules(const ElementType *) const;
106 const SourceLinkRule &linkRule(const ElementType *, size_t) const;
107 void addLinkRule(const ElementType *,
108 const ConstPtr<SourceLinkRuleResource> &);
109 size_t nImpliedLinkRules() const;
110 const ResultElementSpec &impliedLinkRule(size_t) const;
111 Boolean impliedResultAttributes(const ElementType *,
112 const AttributeList *&);
113 private:
114 LinkSet(const LinkSet &); // undefined
115 void operator=(const LinkSet &); // undefined
116 Boolean defined_;
117 // indexed by typeIndex of source elements
118 Vector<Vector<ConstPtr<SourceLinkRuleResource> > >
119 linkRules_;
120 Vector<ResultElementSpec> impliedSourceLinkRules_;
121 };
122
123 class SP_API IdLinkRule : public SourceLinkRule {
124 public:
125 IdLinkRule();
126 Boolean isAssociatedWith(const ElementType *) const;
127 void setAssocElementTypes(Vector<const ElementType *> &);
128 void swap(IdLinkRule &);
129 private:
130 Vector<const ElementType *> assocElementTypes_;
131 };
132
133 // A collection of link rules in a ID link set that are
134 // assocated with the same name (unique identifier).
135
136 class SP_API IdLinkRuleGroup : public Named {
137 public:
138 IdLinkRuleGroup(const StringC &);
139 size_t nLinkRules() const;
140 const IdLinkRule &linkRule(size_t) const;
141 void addLinkRule(IdLinkRule &);
142 private:
143 IdLinkRuleGroup(const IdLinkRuleGroup &); // undefined
144 void operator=(const IdLinkRuleGroup &); // undefined
145 Vector<IdLinkRule> linkRules_;
146 };
147
148 // An implicit or explicit LPD.
149
150 class SP_API ComplexLpd : public Lpd {
151 public:
152 typedef ConstNamedTableIter<LinkSet> ConstLinkSetIter;
153 ComplexLpd(const StringC &, Type,
154 const Location &,
155 const Syntax &syntax,
156 const Ptr<Dtd> &sourceDtd,
157 const Ptr<Dtd> &resultDtd);
158 size_t allocAttributeDefinitionListIndex();
159 size_t nAttributeDefinitionList() const;
160 LinkSet *initialLinkSet();
161 const LinkSet *initialLinkSet() const;
162 const LinkSet *emptyLinkSet() const;
163 const LinkSet *lookupLinkSet(const StringC &) const;
164 const IdLinkRuleGroup *lookupIdLink(const StringC &) const;
165 IdLinkRuleGroup *lookupCreateIdLink(const StringC &);
166 void insertIdLink(IdLinkRuleGroup *);
167 ConstLinkSetIter linkSetIter() const;
168 Boolean hadIdLinkSet() const;
169 void setHadIdLinkSet();
170
171 LinkSet *lookupLinkSet(const StringC &);
172 LinkSet *insertLinkSet(LinkSet *);
173 const Ptr<Dtd> &resultDtd();
174 ConstPtr<Dtd> resultDtd() const;
175 const ConstPtr<AttributeDefinitionList> &
176 attributeDef(const ElementType *) const;
177 void setAttributeDef(const ElementType *,
178 const ConstPtr<AttributeDefinitionList> &);
179 private:
180 ComplexLpd(const ComplexLpd &); // undefined
181 void operator=(const ComplexLpd &); // undefined
182 Ptr<Dtd> resultDtd_;
183 Vector<ConstPtr<AttributeDefinitionList> > linkAttributeDefs_;
184 NamedTable<LinkSet> linkSetTable_;
185 LinkSet initialLinkSet_;
186 LinkSet emptyLinkSet_;
187 Boolean hadIdLinkSet_;
188 NamedTable<IdLinkRuleGroup> idLinkTable_;
189 size_t nAttributeDefinitionList_;
190 };
191
192 inline
type()193 Lpd::Type Lpd::type() const
194 {
195 return type_;
196 }
197
198 inline
location()199 const Location &Lpd::location() const
200 {
201 return location_;
202 }
203
204 inline
active()205 Boolean Lpd::active() const
206 {
207 return active_;
208 }
209
210 inline
activate()211 void Lpd::activate()
212 {
213 active_ = 1;
214 }
215
216 inline
sourceDtd()217 ConstPtr<Dtd> Lpd::sourceDtd() const
218 {
219 return sourceDtd_;
220 }
221
222 inline
sourceDtd()223 const Ptr<Dtd> &Lpd::sourceDtd()
224 {
225 return sourceDtd_;
226 }
227
228 inline
namePointer()229 const ConstPtr<StringResource<Char> > &Lpd::namePointer() const
230 {
231 return name_;
232 }
233
234 inline
name()235 const StringC &Lpd::name() const
236 {
237 return *name_;
238 }
239
240 inline
setLinkAttributes(AttributeList & attributes)241 void SourceLinkRule::setLinkAttributes(AttributeList &attributes)
242 {
243 attributes.swap(linkAttributes_);
244 }
245
246 inline
attributes()247 const AttributeList &SourceLinkRule::attributes() const
248 {
249 return linkAttributes_;
250 }
251
252 inline
setResult(const ElementType * element,AttributeList & attributes)253 void SourceLinkRule::setResult(const ElementType *element,
254 AttributeList &attributes)
255 {
256 resultElementSpec_.elementType = element;
257 attributes.swap(resultElementSpec_.attributeList);
258 }
259
260 inline
resultElementSpec()261 const ResultElementSpec &SourceLinkRule::resultElementSpec() const
262 {
263 return resultElementSpec_;
264 }
265
266 inline
setUselink(const LinkSet * linkSet)267 void SourceLinkRule::setUselink(const LinkSet *linkSet)
268 {
269 uselink_ = linkSet;
270 }
271
272 inline
setPostlink(const LinkSet * linkSet)273 void SourceLinkRule::setPostlink(const LinkSet *linkSet)
274 {
275 postlink_ = linkSet;
276 }
277
278 inline
setPostlinkRestore()279 void SourceLinkRule::setPostlinkRestore()
280 {
281 postlinkRestore_ = 1;
282 }
283
284 inline
uselink()285 const LinkSet *SourceLinkRule::uselink() const
286 {
287 return uselink_;
288 }
289
290 inline
postlink()291 const LinkSet *SourceLinkRule::postlink() const
292 {
293 return postlink_;
294 }
295
296 inline
postlinkRestore()297 Boolean SourceLinkRule::postlinkRestore() const
298 {
299 return postlinkRestore_;
300 }
301
302 inline
defined()303 Boolean LinkSet::defined() const
304 {
305 return defined_;
306 }
307
308 inline
setDefined()309 void LinkSet::setDefined()
310 {
311 defined_ = 1;
312 }
313
314 inline
linkRule(const ElementType * e,size_t i)315 const SourceLinkRule &LinkSet::linkRule(const ElementType *e, size_t i) const
316 {
317 return *linkRules_[e->index()][i];
318 }
319
320 inline
nImpliedLinkRules()321 size_t LinkSet::nImpliedLinkRules() const
322 {
323 return impliedSourceLinkRules_.size();
324 }
325
326 inline
impliedLinkRule(size_t i)327 const ResultElementSpec &LinkSet::impliedLinkRule(size_t i) const
328 {
329 return impliedSourceLinkRules_[i];
330 }
331
332 inline
resultDtd()333 const Ptr<Dtd> &ComplexLpd::resultDtd()
334 {
335 return resultDtd_;
336 }
337
338 inline
resultDtd()339 ConstPtr<Dtd> ComplexLpd::resultDtd() const
340 {
341 return resultDtd_;
342 }
343
344 inline
initialLinkSet()345 LinkSet *ComplexLpd::initialLinkSet()
346 {
347 return &initialLinkSet_;
348 }
349
350 inline
initialLinkSet()351 const LinkSet *ComplexLpd::initialLinkSet() const
352 {
353 return &initialLinkSet_;
354 }
355
356 inline
emptyLinkSet()357 const LinkSet *ComplexLpd::emptyLinkSet() const
358 {
359 return &emptyLinkSet_;
360 }
361
362 inline
lookupLinkSet(const StringC & name)363 const LinkSet *ComplexLpd::lookupLinkSet(const StringC &name) const
364 {
365 return linkSetTable_.lookup(name);
366 }
367
368 inline
lookupLinkSet(const StringC & name)369 LinkSet *ComplexLpd::lookupLinkSet(const StringC &name)
370 {
371 return linkSetTable_.lookup(name);
372 }
373
374 inline
insertLinkSet(LinkSet * e)375 LinkSet *ComplexLpd::insertLinkSet(LinkSet *e)
376 {
377 return linkSetTable_.insert(e);
378 }
379
380 inline
nAttributeDefinitionList()381 size_t ComplexLpd::nAttributeDefinitionList() const
382 {
383 return nAttributeDefinitionList_;
384 }
385
386 inline
allocAttributeDefinitionListIndex()387 size_t ComplexLpd::allocAttributeDefinitionListIndex()
388 {
389 return nAttributeDefinitionList_++;
390 }
391
392 inline
linkSetIter()393 ComplexLpd::ConstLinkSetIter ComplexLpd::linkSetIter() const
394 {
395 // Avoid use of typedef to work around MSVC 2.0 bug.
396 return ConstNamedTableIter<LinkSet>(linkSetTable_);
397 }
398
399 inline
400 const ConstPtr<AttributeDefinitionList> &
attributeDef(const ElementType * e)401 ComplexLpd::attributeDef(const ElementType *e) const
402 {
403 return linkAttributeDefs_[e->index()];
404 }
405
406 inline
setAttributeDef(const ElementType * e,const ConstPtr<AttributeDefinitionList> & attdef)407 void ComplexLpd::setAttributeDef(const ElementType *e,
408 const ConstPtr<AttributeDefinitionList> &attdef)
409 {
410 linkAttributeDefs_[e->index()] = attdef;
411 }
412
413 inline
hadIdLinkSet()414 Boolean ComplexLpd::hadIdLinkSet() const
415 {
416 return hadIdLinkSet_;
417 }
418
419 inline
setHadIdLinkSet()420 void ComplexLpd::setHadIdLinkSet()
421 {
422 hadIdLinkSet_ = 1;
423 }
424
425 inline
lookupIdLink(const StringC & id)426 const IdLinkRuleGroup *ComplexLpd::lookupIdLink(const StringC &id) const
427 {
428 return idLinkTable_.lookup(id);
429 }
430
431 inline
nLinkRules()432 size_t IdLinkRuleGroup::nLinkRules() const
433 {
434 return linkRules_.size();
435 }
436
437 inline
linkRule(size_t i)438 const IdLinkRule &IdLinkRuleGroup::linkRule(size_t i) const
439 {
440 return linkRules_[i];
441 }
442
443 #ifdef SP_NAMESPACE
444 }
445 #endif
446
447 #endif /* not Lpd_INCLUDED */
448