1 /* $XConsortium: ContentState.C /main/1 1996/07/29 16:48:21 cde-hp $ */
2 // Copyright (c) 1994, 1996 James Clark
3 // See the file COPYING for copying permission.
10 #include "ContentState.h"
11 #include "IListIter.h"
16 namespace SP_NAMESPACE {
19 const ShortReferenceMap ContentState::theEmptyMap;
22 typedef IListIter<OpenElement> Dummy_IListIter_OpenElement;
25 ContentState::ContentState()
26 : documentElementContainer_(StringC(), size_t(-1))
30 void ContentState::startContent(const Dtd &dtd)
32 NCVector<Owner<ContentToken> > tokens(1);
33 tokens[0] = new ElementToken(dtd.documentElementType(),
35 Owner<ModelGroup> model(new SeqModelGroup(tokens, ContentToken::none));
36 Owner<CompiledModelGroup> compiledModel(new CompiledModelGroup(model));
37 Vector<ContentModelAmbiguity> ambiguities;
38 Boolean pcdataUnreachable;
39 compiledModel->compile(dtd.nElementTypeIndex(), ambiguities,
41 ASSERT(ambiguities.size() == 0);
42 ConstPtr<ElementDefinition> def
43 = new ElementDefinition(Location(),
46 ElementDefinition::modelGroup,
48 documentElementContainer_.setElementDefinition(def, 0);
50 while (!openElements_.empty())
51 delete openElements_.get();
52 openElements_.insert(new OpenElement(&documentElementContainer_,
57 includeCount_.assign(dtd.nElementTypeIndex(), 0);
58 excludeCount_.assign(dtd.nElementTypeIndex(), 0);
59 openElementCount_.assign(dtd.nElementTypeIndex(), 0);
60 netEnablingCount_ = 0;
61 totalExcludeCount_ = 0;
62 lastEndedElementType_ = 0;
63 undefinedElementTypeTable_.clear();
66 void ContentState::pushElement(OpenElement *e)
69 openElementCount_[e->type()->index()]++;
70 const ElementDefinition *def = e->type()->definition();
73 for (i = 0; i < def->nInclusions(); i++)
74 includeCount_[def->inclusion(i)->index()]++;
75 for (i = 0; i < def->nExclusions(); i++) {
76 excludeCount_[def->exclusion(i)->index()]++;
82 openElements_.insert(e);
85 OpenElement *ContentState::popSaveElement()
87 ASSERT(tagLevel_ > 0);
88 OpenElement *e = openElements_.get();
90 openElementCount_[e->type()->index()]--;
91 const ElementDefinition *def = e->type()->definition();
94 for (i = 0; i < def->nInclusions(); i++)
95 includeCount_[def->inclusion(i)->index()]--;
96 for (i = 0; i < def->nExclusions(); i++) {
97 excludeCount_[def->exclusion(i)->index()]--;
101 if (e->netEnabling())
103 lastEndedElementType_ = e->type();
107 void ContentState::popElement()
109 delete popSaveElement();
112 Boolean ContentState::checkImplyLoop(unsigned count)
114 for (IListIter<OpenElement> iter(openElements_);
116 iter.next(), count--)
117 if (iter.cur()->type() == openElements_.head()->type()
118 // I'm not sure whether this is necessary.
119 && iter.cur()->matchState() == openElements_.head()->matchState())
124 void ContentState::getOpenElementInfo(Vector<OpenElementInfo> &v,
125 const StringC &rniPcdata) const
129 unsigned i = tagLevel_;
130 for (IListIter<OpenElement> iter(openElements_);
131 !iter.done() && i > 0;
133 OpenElementInfo &e = v[--i];
134 e.gi = iter.cur()->type()->name();
135 const LeafContentToken *token = iter.cur()->currentPosition();
136 if (token && !token->isInitial()) {
137 e.matchIndex = token->typeIndex() + 1;
138 const ElementType *type = token->elementType();
139 e.matchType = type ? type->name() : rniPcdata;
141 e.included = iter.cur()->included();
146 ContentState::lookupCreateUndefinedElement(const StringC &name,
149 const ElementType *e = undefinedElementTypeTable_.lookup(name);
152 ElementType *p = new ElementType(name,
153 openElementCount_.size());
154 p->setElementDefinition(new ElementDefinition(loc,
155 ElementDefinition::undefinedIndex,
156 (ElementDefinition::omitStart
157 |ElementDefinition::omitEnd),
158 ElementDefinition::any),
160 undefinedElementTypeTable_.insert(p);
161 includeCount_.push_back(0);
162 excludeCount_.push_back(0);
163 openElementCount_.push_back(0);