1 // Copyright (c) 1996 James Clark
2 // See the file copying.txt for copying permission.
5 #include "NumberCache.h"
9 namespace DSSSL_NAMESPACE {
12 NumberCache::NumberCache()
17 void advance(NodePtr &node)
19 if (node.assignNextChunkAfter() != accessOK)
23 // This caching scheme will be defeated (but not disastrously so)
24 // by numbering both notes and footnotes, say, per chapter.
26 unsigned long NumberCache::elementNumberAfter(const NodePtr &node, const StringC &gi,
27 const StringC &resetGi)
31 unsigned long resetCount = 0;
32 unsigned long count = 0;
33 ElementEntry *entry = elementNumbers_.lookup(resetGi);
35 unsigned long nodeIndex, entryIndex;
37 node->elementIndex(nodeIndex);
38 unsigned long nodeGroveIndex = node->groveIndex();
40 if (*entry->node == *node)
42 entry->node->elementIndex(entryIndex);
43 if (entryIndex < nodeIndex && entry->node->groveIndex() == nodeGroveIndex) {
44 start = lastMatch = entry->node;
46 resetCount = entry->num;
51 if (entry->subNode && useSubnode) {
53 if (entry->subNode->getGi(tem) == accessOK
54 && tem == GroveString(gi.data(), gi.size())) {
55 if (*entry->subNode == *node)
57 entry->subNode->elementIndex(entryIndex);
58 if (entryIndex < nodeIndex && entry->subNode->groveIndex() == nodeGroveIndex) {
59 start = entry->subNode;
61 count = entry->subNum;
67 elementNumbers_.insert(entry = new ElementEntry(resetGi));
69 node->getGroveRoot(start);
70 start->getDocumentElement(start);
74 if (start->getGi(tem) == accessOK) {
75 if (tem == GroveString(resetGi.data(), resetGi.size())) {
80 else if (tem == GroveString(gi.data(), gi.size()))
87 entry->node = lastMatch;
88 entry->num = resetCount;
89 entry->subNode = node;
90 entry->subNum = count;
94 unsigned long NumberCache::elementNumber(const NodePtr &node, const StringC &gi)
98 unsigned long count = 0;
99 ElementEntry *entry = elementNumbers_.lookup(gi);
100 if (entry && entry->node) {
101 if (*entry->node == *node) {
105 unsigned long nodeIndex, entryIndex;
106 entry->node->elementIndex(entryIndex);
107 node->elementIndex(nodeIndex);
108 if (entryIndex < nodeIndex && node->groveIndex() == entry->node->groveIndex()) {
109 lastMatch = start = entry->node;
115 node->getGroveRoot(start);
116 start->getDocumentElement(start);
120 if (start->getGi(tem) == accessOK && tem == GroveString(gi.data(), gi.size())) {
131 elementNumbers_.insert(entry = new ElementEntry(gi));
132 entry->node = lastMatch;
133 entry->subNode.clear();
139 bool NumberCache::childNumber(const NodePtr &node, unsigned long &result)
142 if (node->getGi(gs) != accessOK)
145 if (node->getParent(tem) != accessOK) {
146 // must be document element
152 while (tem->getParent(tem) == accessOK)
154 StringC gi(gs.data(), gs.size());
155 if (level >= childNumbers_.size())
156 childNumbers_.resize(level + 1);
158 unsigned long count = 0;
159 Entry *entry = childNumbers_[level].lookup(gi);
161 if (*entry->node == *node) {
165 // Start counting from the cached entry if it has the same
166 // parent as us and it is before us.
168 entry->node->getParent(entryParent);
169 if (*entryParent == *parent) {
170 unsigned long nodeIndex, entryIndex;
171 entry->node->elementIndex(entryIndex);
172 node->elementIndex(nodeIndex);
173 if (entryIndex < nodeIndex && node->groveIndex() == entry->node->groveIndex()) {
180 entry = new Entry(gi);
181 childNumbers_[level].insert(entry);
184 node->firstSibling(start);
185 while (*start != *node) {
187 if (start->getGi(tem) == accessOK && tem == gs)
189 if (start.assignNextChunkSibling() != accessOK)
198 NumberCache::Entry::Entry(const StringC &name)
203 NumberCache::ElementEntry::ElementEntry(const StringC &name)
204 : NumberCache::Entry(name)
208 #ifdef DSSSL_NAMESPACE