2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: ContentState.C /main/1 1996/07/29 16:48:21 cde-hp $ */
24 // Copyright (c) 1994, 1996 James Clark
25 // See the file COPYING for copying permission.
28 #pragma implementation
32 #include "ContentState.h"
33 #include "IListIter.h"
38 namespace SP_NAMESPACE {
41 const ShortReferenceMap ContentState::theEmptyMap;
44 typedef IListIter<OpenElement> Dummy_IListIter_OpenElement;
47 ContentState::ContentState()
48 : documentElementContainer_(StringC(), size_t(-1)),
49 totalExcludeCount_(0),
52 lastEndedElementType_(NULL)
56 void ContentState::startContent(const Dtd &dtd)
58 NCVector<Owner<ContentToken> > tokens(1);
59 tokens[0] = new ElementToken(dtd.documentElementType(),
61 Owner<ModelGroup> model(new SeqModelGroup(tokens, ContentToken::none));
62 Owner<CompiledModelGroup> compiledModel(new CompiledModelGroup(model));
63 Vector<ContentModelAmbiguity> ambiguities;
64 Boolean pcdataUnreachable;
65 compiledModel->compile(dtd.nElementTypeIndex(), ambiguities,
67 ASSERT(ambiguities.size() == 0);
68 ConstPtr<ElementDefinition> def
69 = new ElementDefinition(Location(),
72 ElementDefinition::modelGroup,
74 documentElementContainer_.setElementDefinition(def, 0);
76 while (!openElements_.empty())
77 delete openElements_.get();
78 openElements_.insert(new OpenElement(&documentElementContainer_,
83 includeCount_.assign(dtd.nElementTypeIndex(), 0);
84 excludeCount_.assign(dtd.nElementTypeIndex(), 0);
85 openElementCount_.assign(dtd.nElementTypeIndex(), 0);
86 netEnablingCount_ = 0;
87 totalExcludeCount_ = 0;
88 lastEndedElementType_ = 0;
89 undefinedElementTypeTable_.clear();
92 void ContentState::pushElement(OpenElement *e)
95 openElementCount_[e->type()->index()]++;
96 const ElementDefinition *def = e->type()->definition();
99 for (i = 0; i < def->nInclusions(); i++)
100 includeCount_[def->inclusion(i)->index()]++;
101 for (i = 0; i < def->nExclusions(); i++) {
102 excludeCount_[def->exclusion(i)->index()]++;
103 totalExcludeCount_++;
106 if (e->netEnabling())
108 openElements_.insert(e);
111 OpenElement *ContentState::popSaveElement()
113 ASSERT(tagLevel_ > 0);
114 OpenElement *e = openElements_.get();
116 openElementCount_[e->type()->index()]--;
117 const ElementDefinition *def = e->type()->definition();
120 for (i = 0; i < def->nInclusions(); i++)
121 includeCount_[def->inclusion(i)->index()]--;
122 for (i = 0; i < def->nExclusions(); i++) {
123 excludeCount_[def->exclusion(i)->index()]--;
124 totalExcludeCount_--;
127 if (e->netEnabling())
129 lastEndedElementType_ = e->type();
133 void ContentState::popElement()
135 delete popSaveElement();
138 Boolean ContentState::checkImplyLoop(unsigned count)
140 for (IListIter<OpenElement> iter(openElements_);
142 iter.next(), count--)
143 if (iter.cur()->type() == openElements_.head()->type()
144 // I'm not sure whether this is necessary.
145 && iter.cur()->matchState() == openElements_.head()->matchState())
150 void ContentState::getOpenElementInfo(Vector<OpenElementInfo> &v,
151 const StringC &rniPcdata) const
155 unsigned i = tagLevel_;
156 for (IListIter<OpenElement> iter(openElements_);
157 !iter.done() && i > 0;
159 OpenElementInfo &e = v[--i];
160 e.gi = iter.cur()->type()->name();
161 const LeafContentToken *token = iter.cur()->currentPosition();
162 if (token && !token->isInitial()) {
163 e.matchIndex = token->typeIndex() + 1;
164 const ElementType *type = token->elementType();
165 e.matchType = type ? type->name() : rniPcdata;
167 e.included = iter.cur()->included();
172 ContentState::lookupCreateUndefinedElement(const StringC &name,
175 const ElementType *e = undefinedElementTypeTable_.lookup(name);
178 ElementType *p = new ElementType(name,
179 openElementCount_.size());
180 p->setElementDefinition(new ElementDefinition(loc,
181 ElementDefinition::undefinedIndex,
182 (ElementDefinition::omitStart
183 |ElementDefinition::omitEnd),
184 ElementDefinition::any),
186 undefinedElementTypeTable_.insert(p);
187 includeCount_.push_back(0);
188 excludeCount_.push_back(0);
189 openElementCount_.push_back(0);