ContentState.C 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  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)
  10. * any later version.
  11. *
  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
  16. * details.
  17. *
  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
  22. */
  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.
  26. #ifdef __GNUG__
  27. #pragma implementation
  28. #endif
  29. #include "splib.h"
  30. #include "ContentState.h"
  31. #include "IListIter.h"
  32. #include "NCVector.h"
  33. #include "macros.h"
  34. #ifdef SP_NAMESPACE
  35. namespace SP_NAMESPACE {
  36. #endif
  37. const ShortReferenceMap ContentState::theEmptyMap;
  38. #ifdef __GNUG__
  39. typedef IListIter<OpenElement> Dummy_IListIter_OpenElement;
  40. #endif
  41. ContentState::ContentState()
  42. : documentElementContainer_(StringC(), size_t(-1)),
  43. totalExcludeCount_(0),
  44. tagLevel_(0),
  45. netEnablingCount_(0),
  46. lastEndedElementType_(NULL)
  47. {
  48. }
  49. void ContentState::startContent(const Dtd &dtd)
  50. {
  51. NCVector<Owner<ContentToken> > tokens(1);
  52. tokens[0] = new ElementToken(dtd.documentElementType(),
  53. ContentToken::none);
  54. Owner<ModelGroup> model(new SeqModelGroup(tokens, ContentToken::none));
  55. Owner<CompiledModelGroup> compiledModel(new CompiledModelGroup(model));
  56. Vector<ContentModelAmbiguity> ambiguities;
  57. Boolean pcdataUnreachable;
  58. compiledModel->compile(dtd.nElementTypeIndex(), ambiguities,
  59. pcdataUnreachable);
  60. ASSERT(ambiguities.size() == 0);
  61. ConstPtr<ElementDefinition> def
  62. = new ElementDefinition(Location(),
  63. 0,
  64. 0,
  65. ElementDefinition::modelGroup,
  66. compiledModel);
  67. documentElementContainer_.setElementDefinition(def, 0);
  68. tagLevel_ = 0;
  69. while (!openElements_.empty())
  70. delete openElements_.get();
  71. openElements_.insert(new OpenElement(&documentElementContainer_,
  72. 0,
  73. 0,
  74. &theEmptyMap,
  75. Location()));
  76. includeCount_.assign(dtd.nElementTypeIndex(), 0);
  77. excludeCount_.assign(dtd.nElementTypeIndex(), 0);
  78. openElementCount_.assign(dtd.nElementTypeIndex(), 0);
  79. netEnablingCount_ = 0;
  80. totalExcludeCount_ = 0;
  81. lastEndedElementType_ = 0;
  82. undefinedElementTypeTable_.clear();
  83. }
  84. void ContentState::pushElement(OpenElement *e)
  85. {
  86. tagLevel_++;
  87. openElementCount_[e->type()->index()]++;
  88. const ElementDefinition *def = e->type()->definition();
  89. if (def) {
  90. size_t i;
  91. for (i = 0; i < def->nInclusions(); i++)
  92. includeCount_[def->inclusion(i)->index()]++;
  93. for (i = 0; i < def->nExclusions(); i++) {
  94. excludeCount_[def->exclusion(i)->index()]++;
  95. totalExcludeCount_++;
  96. }
  97. }
  98. if (e->netEnabling())
  99. netEnablingCount_++;
  100. openElements_.insert(e);
  101. }
  102. OpenElement *ContentState::popSaveElement()
  103. {
  104. ASSERT(tagLevel_ > 0);
  105. OpenElement *e = openElements_.get();
  106. tagLevel_--;
  107. openElementCount_[e->type()->index()]--;
  108. const ElementDefinition *def = e->type()->definition();
  109. if (def) {
  110. size_t i;
  111. for (i = 0; i < def->nInclusions(); i++)
  112. includeCount_[def->inclusion(i)->index()]--;
  113. for (i = 0; i < def->nExclusions(); i++) {
  114. excludeCount_[def->exclusion(i)->index()]--;
  115. totalExcludeCount_--;
  116. }
  117. }
  118. if (e->netEnabling())
  119. netEnablingCount_--;
  120. lastEndedElementType_ = e->type();
  121. return e;
  122. }
  123. void ContentState::popElement()
  124. {
  125. delete popSaveElement();
  126. }
  127. Boolean ContentState::checkImplyLoop(unsigned count)
  128. {
  129. for (IListIter<OpenElement> iter(openElements_);
  130. count > 0;
  131. iter.next(), count--)
  132. if (iter.cur()->type() == openElements_.head()->type()
  133. // I'm not sure whether this is necessary.
  134. && iter.cur()->matchState() == openElements_.head()->matchState())
  135. return 0;
  136. return 1;
  137. }
  138. void ContentState::getOpenElementInfo(Vector<OpenElementInfo> &v,
  139. const StringC &rniPcdata) const
  140. {
  141. v.clear();
  142. v.resize(tagLevel_);
  143. unsigned i = tagLevel_;
  144. for (IListIter<OpenElement> iter(openElements_);
  145. !iter.done() && i > 0;
  146. iter.next()) {
  147. OpenElementInfo &e = v[--i];
  148. e.gi = iter.cur()->type()->name();
  149. const LeafContentToken *token = iter.cur()->currentPosition();
  150. if (token && !token->isInitial()) {
  151. e.matchIndex = token->typeIndex() + 1;
  152. const ElementType *type = token->elementType();
  153. e.matchType = type ? type->name() : rniPcdata;
  154. }
  155. e.included = iter.cur()->included();
  156. }
  157. }
  158. const ElementType *
  159. ContentState::lookupCreateUndefinedElement(const StringC &name,
  160. const Location &loc)
  161. {
  162. const ElementType *e = undefinedElementTypeTable_.lookup(name);
  163. if (e)
  164. return e;
  165. ElementType *p = new ElementType(name,
  166. openElementCount_.size());
  167. p->setElementDefinition(new ElementDefinition(loc,
  168. ElementDefinition::undefinedIndex,
  169. (ElementDefinition::omitStart
  170. |ElementDefinition::omitEnd),
  171. ElementDefinition::any),
  172. 0);
  173. undefinedElementTypeTable_.insert(p);
  174. includeCount_.push_back(0);
  175. excludeCount_.push_back(0);
  176. openElementCount_.push_back(0);
  177. return p;
  178. }
  179. #ifdef SP_NAMESPACE
  180. }
  181. #endif