1 // Copyright (c) 1994, 1996 James Clark
2 // See the file COPYING for copying permission.
3 #pragma ident "%Z%%M% %I% %E% SMI"
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;
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 e
->setIndex(nextIndex_
++);
83 openElements_
.insert(e
);
86 OpenElement
*ContentState::popSaveElement()
88 ASSERT(tagLevel_
> 0);
89 OpenElement
*e
= openElements_
.get();
91 openElementCount_
[e
->type()->index()]--;
92 const ElementDefinition
*def
= e
->type()->definition();
95 for (i
= 0; i
< def
->nInclusions(); i
++)
96 includeCount_
[def
->inclusion(i
)->index()]--;
97 for (i
= 0; i
< def
->nExclusions(); i
++) {
98 excludeCount_
[def
->exclusion(i
)->index()]--;
102 if (e
->netEnabling())
104 lastEndedElementType_
= e
->type();
108 void ContentState::popElement()
110 delete popSaveElement();
113 Boolean
ContentState::checkImplyLoop(unsigned count
)
115 for (IListIter
<OpenElement
> iter(openElements_
);
117 iter
.next(), count
--)
118 if (iter
.cur()->type() == openElements_
.head()->type()
119 // I'm not sure whether this is necessary.
120 && iter
.cur()->matchState() == openElements_
.head()->matchState())
125 void ContentState::getOpenElementInfo(Vector
<OpenElementInfo
> &v
,
126 const StringC
&rniPcdata
) const
130 unsigned i
= tagLevel_
;
131 for (IListIter
<OpenElement
> iter(openElements_
);
132 !iter
.done() && i
> 0;
134 OpenElementInfo
&e
= v
[--i
];
135 e
.gi
= iter
.cur()->type()->name();
136 const LeafContentToken
*token
= iter
.cur()->currentPosition();
137 if (token
&& !token
->isInitial()) {
138 e
.matchIndex
= token
->typeIndex() + 1;
139 const ElementType
*type
= token
->elementType();
140 e
.matchType
= type
? type
->name() : rniPcdata
;
142 e
.included
= iter
.cur()->included();
147 ContentState::lookupCreateUndefinedElement(const StringC
&name
,
151 ElementType
*p
= new ElementType(name
,
152 dtd
.allocElementTypeIndex());
153 dtd
.insertUndefinedElementType(p
);
154 p
->setElementDefinition(new ElementDefinition(loc
,
155 size_t(ElementDefinition::undefinedIndex
),
157 ElementDefinition::any
),
159 p
->setAttributeDef(dtd
.implicitElementAttributeDef());
161 includeCount_
.push_back(0);
162 excludeCount_
.push_back(0);
163 openElementCount_
.push_back(0);