1 // Copyright (c) 1996, 1997 James Clark
2 // See the file COPYING for copying permission.
3 
4 // FIXME location for SgmlDocument node.
5 
6 #include "config.h"
7 #include "Boolean.h"
8 #include "Node.h"
9 #include "Resource.h"
10 #include "Ptr.h"
11 #include "xnew.h"
12 #include "Event.h"
13 #include "GroveBuilder.h"
14 #include "ErrorCountEventHandler.h"
15 #include "OutputCharStream.h"
16 #include "MessageFormatter.h"
17 #include "Dtd.h"
18 #include "Syntax.h"
19 #include "Attribute.h"
20 #include "Vector.h"
21 #include "LocNode.h"
22 #include "SdNode.h"
23 #include "threads.h"
24 #include "macros.h"
25 
26 #ifdef _MSC_VER
27 #pragma warning ( disable : 4250 ) // inherits via dominance
28 #endif
29 
30 #include <stddef.h>
31 #include <string.h>
32 
33 #ifdef SP_NAMESPACE
34 namespace SP_NAMESPACE {
35 #endif
36 
37 #ifdef GROVE_NAMESPACE
38 using namespace GROVE_NAMESPACE;
39 #endif
40 
41 static bool blockingAccess = 1;
42 
43 size_t initialBlockSize = 8192;
44 unsigned maxBlocksPerSize = 20;
45 
46 struct Chunk;
47 struct ParentChunk;
48 class ElementChunk;
49 struct SgmlDocumentChunk;
50 class DataChunk;
51 class GroveImpl;
52 class BaseNode;
53 class ChunkNode;
54 class ElementNode;
55 class DataNode;
56 class CdataAttributeValueNode;
57 class AttributeValueTokenNode;
58 class AttributeAsgnNode;
59 class EntityNode;
60 class NotationNode;
61 class ExternalIdNode;
62 class DocumentTypeNode;
63 class SgmlConstantsNode;
64 class MessageNode;
65 
66 struct Chunk {
67   // second arg never null
68   // Set ptr to a node pointing to first Node in this.
69   virtual AccessResult setNodePtrFirst(NodePtr &ptr,
70 				       const BaseNode *) const = 0;
71   virtual AccessResult setNodePtrFirst(NodePtr &ptr,
72 				       const ElementNode *node) const;
73   virtual AccessResult setNodePtrFirst(NodePtr &ptr,
74 				       const DataNode *node) const;
75   virtual const Chunk *after() const = 0;
76   virtual AccessResult getFollowing(const GroveImpl *,
77                                     const Chunk *&, unsigned long &nNodes)
78     const;
79   virtual AccessResult getFirstSibling(const GroveImpl *, const Chunk *&) const;
80   virtual const StringC *id() const;
81   virtual Boolean getLocOrigin(const Origin *&) const;
82   ParentChunk *origin;
83 };
84 
85 struct LocChunk : public Chunk {
86   Index locIndex;
87 };
88 
89 struct ParentChunk : public LocChunk {
ParentChunkSP_NAMESPACE::ParentChunk90   ParentChunk() : nextSibling(0) { }
91   Chunk *nextSibling;
92 };
93 
94 class ElementChunk : public ParentChunk {
95 public:
96   virtual const AttributeValue *
97     attributeValue(size_t attIndex, const GroveImpl &grove) const;
98   virtual Boolean mustOmitEndTag() const;
99   virtual Boolean included() const;
100   const AttributeDefinitionList *attDefList() const;
101   AccessResult setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const;
102   AccessResult setNodePtrFirst(NodePtr &ptr, const DataNode *node) const;
103   AccessResult setNodePtrFirst(NodePtr &ptr, const ElementNode *node) const;
key(const ElementChunk & chunk)104   static const StringC &key(const ElementChunk &chunk) { return *chunk.id(); }
105   const Chunk *after() const;
106   AccessResult getFollowing(const GroveImpl *, const Chunk *&, unsigned long &nNodes)
107     const;
108 private:
109   friend class ElementNode;
110   const ElementType *type;
111 public:
112   unsigned long elementIndex;
113 };
114 
115 inline
attDefList() const116 const AttributeDefinitionList *ElementChunk::attDefList() const
117 {
118   return type->attributeDefTemp();
119 }
120 
121 class LocOriginChunk : public Chunk {
122 public:
LocOriginChunk(const Origin * lo)123   LocOriginChunk(const Origin *lo) : locOrigin(lo) { }
124   AccessResult setNodePtrFirst(NodePtr &ptr, const BaseNode *) const;
125   AccessResult setNodePtrFirst(NodePtr &ptr, const ElementNode *node) const;
126   AccessResult setNodePtrFirst(NodePtr &ptr, const DataNode *node) const;
127   const Chunk *after() const;
128   AccessResult getFollowing(const GroveImpl *,
129                             const Chunk *&, unsigned long &nNodes)
130     const;
131   Boolean getLocOrigin(const Origin *&) const;
132 private:
133   const Origin *locOrigin;
134 };
135 
136 class MessageItem {
137 public:
MessageItem(Node::Severity severity,const StringC & text,const Location & loc)138   MessageItem(Node::Severity severity, const StringC &text, const Location &loc)
139     : severity_(severity), text_(text), loc_(loc), next_(0) { }
severity() const140   Node::Severity severity() const { return severity_; }
loc() const141   const Location &loc() const { return loc_; }
text() const142   const StringC &text() const { return text_; }
next() const143   const MessageItem *next() const { return next_; }
nextP()144   MessageItem **nextP() { return &next_; }
145 private:
146   Node::Severity severity_;
147   StringC text_;
148   Location loc_;
149   MessageItem *next_;
150 };
151 
152 // multiple threads using const interface.
153 
154 class GroveImpl {
155 public:
156   GroveImpl(unsigned groveIndex);
157 
158   // Const interface
addRef() const159   void addRef() const { ++(((GroveImpl *)this)->refCount_); }
release() const160   void release() const {
161     if (!--(((GroveImpl *)this)->refCount_))
162       delete (GroveImpl *)this;
163   }
groveIndex() const164   unsigned groveIndex() const { return groveIndex_; }
root() const165   const SgmlDocumentChunk *root() const { return root_; }
impliedAttributeValue() const166   const AttributeValue *impliedAttributeValue() const {
167     return impliedAttributeValue_.pointer();
168   }
169   // Return 0 if not yet available.
170   Boolean getAppinfo(const StringC *&) const;
generalSubstTable() const171   const SubstTable<Char> *generalSubstTable() const {
172     return instanceSyntax_.isNull() ? 0 : instanceSyntax_->generalSubstTable();
173   }
entitySubstTable() const174   const SubstTable<Char> *entitySubstTable() const {
175     return instanceSyntax_.isNull() ? 0 : instanceSyntax_->entitySubstTable();
176   }
177   // Be careful not to change ref counts while accessing DTD.
governingDtd() const178   const Dtd *governingDtd() const { return dtd_.pointer(); }
179   // must not be called till grove is complete
180   Dtd::ConstEntityIter defaultedEntityIter() const;
181   const Entity *lookupDefaultedEntity(const StringC &) const;
182   const ElementChunk *lookupElement(const StringC &) const;
183   typedef PointerTableIter<ElementChunk *,StringC,Hash,ElementChunk> ElementIter;
184   // must not be called till grove is complete
185   ElementIter elementIter() const;
complete() const186   Boolean complete() const { return complete_; }
completeLimit() const187   const void *completeLimit() const { return completeLimit_; }
completeLimitWithLocChunkAfter() const188   const void *completeLimitWithLocChunkAfter() const {
189     return completeLimitWithLocChunkAfter_;
190   }
currentLocOrigin() const191   const Origin *currentLocOrigin() const { return currentLocOrigin_; }
hasDefaultEntity() const192   Boolean hasDefaultEntity() const { return hasDefaultEntity_; }
193   Boolean maybeMoreSiblings(const ParentChunk *chunk) const;
194   // return zero for timeout
195   Boolean waitForMoreNodes() const;
196   AccessResult proxifyLocation(const Location &, Location &) const;
messageList() const197   const MessageItem *messageList() const { return messageList_; }
198   // must not be called till grove is complete
199   void getSd(ConstPtr<Sd> &, ConstPtr<Syntax> &, ConstPtr<Syntax> &) const;
200   // non-const interface
201   void *allocChunk(size_t);
202   void appendSibling(Chunk *);
203   void appendSibling(DataChunk *);
tryExtend(size_t n)204   Boolean tryExtend(size_t n) {
205     if (n <= nFree_) {
206       nFree_ -= n;
207       freePtr_ += n;
208       return 1;
209     }
210     else
211       return 0;
212   }
pendingData()213   DataChunk *pendingData() { return pendingData_; }
214   void push(ElementChunk *, Boolean hasId);
215   void pop();
216   void setAppinfo(const StringC &);
217   void setDtd(const ConstPtr<Dtd> &dtd);
218   void setSd(const ConstPtr<Sd> &, const ConstPtr<Syntax> &, const ConstPtr<Syntax> &);
storeAttributeValue(const ConstPtr<AttributeValue> & value)219   void storeAttributeValue(const ConstPtr<AttributeValue> &value) {
220     values_.push_back(value);
221   }
222   void addDefaultedEntity(const ConstPtr<Entity> &);
223   void setComplete();
224   Boolean haveRootOrigin();
225   void setLocOrigin(const ConstPtr<Origin> &);
226   void appendMessage(MessageItem *);
227 private:
228   GroveImpl(const GroveImpl &);
229   void operator=(const GroveImpl &);
230   ~GroveImpl();
231 
232   Boolean maybeMoreSiblings1(const ParentChunk *) const;
233   void *allocFinish(size_t);
234   void pulse();
235   void maybePulse();
236   void finishDocumentElement();
237   void finishProlog();
238   void addBarrier();
239   void storeLocOrigin(const ConstPtr<Origin> &);
240 
241   struct BlockHeader {
BlockHeaderSP_NAMESPACE::GroveImpl::BlockHeader242     BlockHeader() : next(0) { }
243     BlockHeader *next;
244   };
245   unsigned groveIndex_;
246   SgmlDocumentChunk *root_;
247   ParentChunk *origin_;
248   DataChunk *pendingData_;
249   Chunk **tailPtr_;
250   ConstPtr<Dtd> dtd_;
251   ConstPtr<Sd> sd_;
252   ConstPtr<Syntax> prologSyntax_;
253   ConstPtr<Syntax> instanceSyntax_;
254   ConstPtr<AttributeValue> impliedAttributeValue_;
255   Vector<ConstPtr<AttributeValue> > values_;
256   Vector<ConstPtr<Origin> > origins_;
257   NamedResourceTable<Entity> defaultedEntityTable_;
258   PointerTable<ElementChunk *,StringC,Hash,ElementChunk> idTable_;
259   Boolean hasDefaultEntity_;
260   Boolean haveAppinfo_;
261   StringC appinfo_;
262   const Origin *currentLocOrigin_;
263 
264   Boolean complete_;
265   const void *completeLimit_;
266   const void *completeLimitWithLocChunkAfter_;
267   // pointer to first free byte in current block
268   char *freePtr_;
269   // free bytes in current block
270   // there's space for a forwarding chunk after this if freePtr_ != 0
271   size_t nFree_;
272   // the head of the list of blocks
273   BlockHeader *blocks_;
274   // where to store pointer to next block
275   BlockHeader **blockTailPtr_;
276   // current normal size for a block
277   size_t blockAllocSize_;
278   // number of blocks allocated at this size
279   size_t nBlocksThisSizeAlloced_;
280   RefCount refCount_;
281   Condition moreNodesCondition_;
282   Mutex mutex_;
283   Mutex *mutexPtr_;
284   unsigned pulseStep_;
285   unsigned long nEvents_;
286   unsigned long nElements_;
287   enum { maxChunksWithoutLocOrigin = 100 };
288   unsigned nChunksSinceLocOrigin_;
289   MessageItem *messageList_;
290   MessageItem **messageListTailP_;
291 };
292 
293 class GroveImplPtr {
294 public:
GroveImplPtr(const GroveImpl * grove)295   GroveImplPtr(const GroveImpl *grove) : grove_(grove) { grove_->addRef(); }
~GroveImplPtr()296   ~GroveImplPtr() { grove_->release(); }
operator ->() const297   const GroveImpl *operator->() const { return grove_; }
operator const GroveImpl*() const298   operator const GroveImpl *() const { return grove_; }
299 private:
300   GroveImplPtr(const GroveImplPtr &); // undefined
301   void operator=(const GroveImplPtr &);	// undefined
302   const GroveImpl *grove_;
303 };
304 
305 class GroveImplProxyOrigin : public ProxyOrigin {
306 public:
GroveImplProxyOrigin(const GroveImpl * grove,const Origin * origin)307   GroveImplProxyOrigin(const GroveImpl *grove, const Origin *origin)
308     : grove_(grove), ProxyOrigin(origin) { }
309 private:
310   GroveImplPtr grove_;
311 };
312 
313 class GroveBuilderMessageEventHandler : public ErrorCountEventHandler {
314 public:
315   GroveBuilderMessageEventHandler(unsigned groveIndex, Messenger *mgr, MessageFormatter *msgFmt_);
316   ~GroveBuilderMessageEventHandler();
317   void message(MessageEvent *);
318   void sgmlDecl(SgmlDeclEvent *);
319   void makeInitialRoot(NodePtr &);
320   void setSd(const ConstPtr<Sd> &, const ConstPtr<Syntax> &, const ConstPtr<Syntax> &);
321 protected:
322   GroveImpl *grove_;
323 private:
324   Messenger *mgr_;
325   MessageFormatter *msgFmt_;
326 };
327 
328 class GroveBuilderEventHandler : public GroveBuilderMessageEventHandler {
329 public:
330   GroveBuilderEventHandler(unsigned groveIndex, Messenger *mgr, MessageFormatter *msgFmt_);
331   void appinfo(AppinfoEvent *);
332   void startElement(StartElementEvent *);
333   void endElement(EndElementEvent *);
334   void data(DataEvent *);
335   void sdataEntity(SdataEntityEvent *);
336   void nonSgmlChar(NonSgmlCharEvent *);
337   void externalDataEntity(ExternalDataEntityEvent *);
338   void subdocEntity(SubdocEntityEvent *);
339   void pi(PiEvent *);
340   void endProlog(EndPrologEvent *);
341   void entityDefaulted(EntityDefaultedEvent *);
342 };
343 
344 inline
setString(GroveString & to,const StringC & from)345 void setString(GroveString &to, const StringC &from)
346 {
347   to.assign(from.data(), from.size());
348 }
349 
350 inline
operator ==(const StringC & str1,const GroveString & str2)351 bool operator==(const StringC &str1, const GroveString &str2)
352 {
353   return (str1.size() == str2.size()
354           && memcmp(str1.data(), str2.data(), str1.size()*sizeof(Char)) == 0);
355 }
356 
357 inline
operator !=(const StringC & str1,const GroveString & str2)358 bool operator!=(const StringC &str1, const GroveString &str2)
359 {
360   return !(str1 == str2);
361 }
362 
363 inline
roundUp(size_t n)364 size_t roundUp(size_t n)
365 {
366   return (n + (sizeof(void *) - 1)) & ~(sizeof(void *) - 1);
367 }
368 
369 // All nodes in this grove must be derived from BaseNode.
370 
371 class BaseNode : public Node, public LocNode {
372 public:
373   BaseNode(const GroveImpl *grove);
374   virtual ~BaseNode();
375   void addRef();
376   void release();
377   bool canReuse(NodePtr &ptr) const;
378   unsigned groveIndex() const;
379   bool operator==(const Node &node) const;
380   // Implemented with double dispatching.
381   virtual bool same(const BaseNode &) const = 0;
382   // The second half of the dispatch.
383   virtual bool same2(const ChunkNode *) const;
384   virtual bool same2(const DataNode *) const;
385   virtual bool same2(const AttributeAsgnNode *) const;
386   virtual bool same2(const AttributeValueTokenNode *) const;
387   virtual bool same2(const CdataAttributeValueNode *) const;
388   virtual bool same2(const EntityNode *) const;
389   virtual bool same2(const NotationNode *) const;
390   virtual bool same2(const ExternalIdNode *) const;
391   virtual bool same2(const DocumentTypeNode *) const;
392   virtual bool same2(const SgmlConstantsNode *) const;
393   virtual bool same2(const MessageNode *) const;
grove() const394   const GroveImpl *grove() const { return grove_; }
395   AccessResult nextSibling(NodePtr &ptr) const;
396   AccessResult follow(NodeListPtr &ptr) const;
397   AccessResult children(NodeListPtr &) const;
398   AccessResult getOrigin(NodePtr &ptr) const;
399   AccessResult getGroveRoot(NodePtr &ptr) const;
400   AccessResult getLocation(Location &) const;
401   bool queryInterface(IID, const void *&) const;
402   bool chunkContains(const Node &) const;
403   bool inChunk(const DataNode *node) const;
404   bool inChunk(const CdataAttributeValueNode *) const;
405 protected:
secondHash(unsigned long n)406   static unsigned long secondHash(unsigned long n) {
407     return n * 1001;
408   }
409 private:
410   unsigned refCount_;
411   GroveImplPtr grove_;
412 };
413 
414 inline
BaseNode(const GroveImpl * grove)415 BaseNode::BaseNode(const GroveImpl *grove)
416 : grove_(grove), refCount_(0)
417 {
418 }
419 
420 inline
canReuse(NodePtr & ptr) const421 bool BaseNode::canReuse(NodePtr &ptr) const
422 {
423   const Node *tem = &*ptr;
424   return tem == this && refCount_ == 1;
425 }
426 
427 struct ForwardingChunk : Chunk {
ForwardingChunkSP_NAMESPACE::ForwardingChunk428   ForwardingChunk(const Chunk *to, ParentChunk *p)
429     : forwardTo(to) { origin = p; }
430   AccessResult setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const;
431   AccessResult getFollowing(const GroveImpl *,
432                             const Chunk *&, unsigned long &nNodes)
433     const;
afterSP_NAMESPACE::ForwardingChunk434   const Chunk *after() const { return forwardTo; }
435   const Chunk *forwardTo;
436 };
437 
438 class ChunkNode : public BaseNode {
439 public:
440   ChunkNode(const GroveImpl *grove, const LocChunk *chunk);
chunk() const441   const LocChunk *chunk() const { return chunk_; }
442   bool same(const BaseNode &node) const;
443   bool same2(const ChunkNode *node) const;
444   unsigned long hash() const;
445   AccessResult getParent(NodePtr &ptr) const;
446   AccessResult getTreeRoot(NodePtr &ptr) const;
447   AccessResult getOrigin(NodePtr &) const;
448   AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &) const;
449   AccessResult nextChunkSibling(NodePtr &) const;
450   AccessResult nextChunkAfter(NodePtr &) const;
451   AccessResult firstSibling(NodePtr &) const;
452   AccessResult siblingsIndex(unsigned long &) const;
453   AccessResult followSiblingRef(unsigned long, NodePtr &) const;
454   AccessResult getLocation(Location &) const;
455 protected:
456   const LocChunk *chunk_;		// never null
457 };
458 
459 inline
ChunkNode(const GroveImpl * grove,const LocChunk * chunk)460 ChunkNode::ChunkNode(const GroveImpl *grove, const LocChunk *chunk)
461 : BaseNode(grove), chunk_(chunk)
462 {
463 }
464 
465 class SgmlDocumentNode;
466 
467 struct SgmlDocumentChunk : public ParentChunk {
SgmlDocumentChunkSP_NAMESPACE::SgmlDocumentChunk468   SgmlDocumentChunk() : prolog(0), documentElement(0), epilog(0) { }
469   Chunk *prolog;
470   Chunk *documentElement;
471   Chunk *epilog;
472   AccessResult setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const;
afterSP_NAMESPACE::SgmlDocumentChunk473   const Chunk *after() const { return this + 1; }
474 };
475 
476 class SgmlDocumentNode : public ChunkNode, public SdNode {
477 public:
478   SgmlDocumentNode(const GroveImpl *grove,
479 		   const SgmlDocumentChunk *chunk);
480   void accept(NodeVisitor &visitor);
classDef() const481   const ClassDef &classDef() const { return ClassDef::sgmlDocument; }
482   AccessResult getDocumentElement(NodePtr &ptr) const;
483   AccessResult getElements(NamedNodeListPtr &ptr) const;
484   AccessResult getEntities(NamedNodeListPtr &ptr) const;
485   AccessResult getDefaultedEntities(NamedNodeListPtr &ptr) const;
486   AccessResult getGoverningDoctype(NodePtr &ptr) const;
487   AccessResult getDoctypesAndLinktypes(NamedNodeListPtr &ptr) const;
488   AccessResult getProlog(NodeListPtr &ptr) const;
489   AccessResult getEpilog(NodeListPtr &ptr) const;
490   AccessResult getSgmlConstants(NodePtr &) const;
491   AccessResult getApplicationInfo(GroveString &str) const;
492   AccessResult getMessages(NodeListPtr &ptr) const;
nextChunkSibling(NodePtr &) const493   AccessResult nextChunkSibling(NodePtr &) const { return accessNotInClass; }
firstSibling(NodePtr &) const494   AccessResult firstSibling(NodePtr &) const { return accessNotInClass; }
siblingsIndex(unsigned long &) const495   AccessResult siblingsIndex(unsigned long &) const { return accessNotInClass; }
getOriginToSubnodeRelPropertyName(ComponentName::Id &) const496   AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &) const { return accessNull; }
497   AccessResult getSd(ConstPtr<Sd> &sd,
498 		     ConstPtr<Syntax> &prologSyntax,
499 		     ConstPtr<Syntax> &instanceSyntax) const;
500 private:
chunk() const501   const SgmlDocumentChunk *chunk() const {
502     return (const SgmlDocumentChunk *)ChunkNode::chunk();
503   }
504 };
505 
506 inline
SgmlDocumentNode(const GroveImpl * grove,const SgmlDocumentChunk * chunk)507 SgmlDocumentNode::SgmlDocumentNode(const GroveImpl *grove,
508 				   const SgmlDocumentChunk *chunk)
509 : ChunkNode(grove, chunk)
510 {
511 }
512 
513 // array of pointers to attribute values stored after chunk
514 
515 class AttElementChunk : private ElementChunk {
516 protected:
AttElementChunk(size_t n)517   AttElementChunk(size_t n) : nAtts(n) { }
518   friend class ElementNode;
519 private:
520   const AttributeValue *
521     attributeValue(size_t attIndex, const GroveImpl &) const;
522   Boolean mustOmitEndTag() const;
523   const Chunk *after() const;
524   const StringC *id() const;
525   size_t nAtts;
526 };
527 
528 class IncludedElementChunk : public ElementChunk {
529   friend class ElementNode;
530   Boolean included() const;
531 };
532 
533 class IncludedAttElementChunk : public AttElementChunk {
IncludedAttElementChunk(size_t n)534   IncludedAttElementChunk(size_t n) : AttElementChunk(n) { }
535   friend class ElementNode;
536   Boolean included() const;
537 };
538 
539 class ElementNode : public ChunkNode {
540 public:
541   friend class ElementChunk;
ElementNode(const GroveImpl * grove,const ElementChunk * chunk)542   ElementNode(const GroveImpl *grove, const ElementChunk *chunk)
543     : ChunkNode(grove, chunk) { }
544   AccessResult attributeRef(unsigned long i, NodePtr &ptr) const;
545   AccessResult nextChunkSibling(NodePtr &ptr) const;
546   AccessResult nextChunkAfter(NodePtr &) const;
547   AccessResult firstChild(NodePtr &ptr) const;
548   AccessResult getAttributes(NamedNodeListPtr &ptr) const;
549   AccessResult getGi(GroveString &str) const;
550   bool hasGi(GroveString) const;
551   AccessResult getId(GroveString &str) const;
552   AccessResult getContent(NodeListPtr &ptr) const;
553   AccessResult getMustOmitEndTag(bool &) const;
554   AccessResult getIncluded(bool &) const;
555   AccessResult elementIndex(unsigned long &) const;
556   void accept(NodeVisitor &visitor);
classDef() const557   const ClassDef &classDef() const { return ClassDef::element; }
558   static void add(GroveImpl &grove, const StartElementEvent &event);
559 private:
560   static
561     ElementChunk *makeAttElementChunk(GroveImpl &grove,
562 				      const StartElementEvent &,
563 				      Boolean &hasId);
chunk() const564   const ElementChunk *chunk() const {
565     return (const ElementChunk *)ChunkNode::chunk();
566   }
reuseFor(const ElementChunk * chunk)567   void reuseFor(const ElementChunk *chunk) { chunk_ = chunk; }
568 };
569 
570 class CharsChunk : public LocChunk {
571 public:
after() const572   const Chunk *after() const {
573     return (const Chunk *)((char *)this + allocSize(size));
574   }
data() const575   const Char *data() const { return (const Char *)(this + 1); }
576   size_t size;
allocSize(size_t nChars)577   static size_t allocSize(size_t nChars) {
578     return roundUp(sizeof(CharsChunk) + nChars*sizeof(Char));
579   }
580 };
581 // The characters immediately follow the chunk
582 
583 class DataChunk : public CharsChunk {
584 private:
585   friend class DataNode;
586   AccessResult setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const;
587   AccessResult setNodePtrFirst(NodePtr &ptr, const ElementNode *node) const;
588   AccessResult setNodePtrFirst(NodePtr &ptr, const DataNode *node) const;
589   AccessResult getFollowing(const GroveImpl *, const Chunk *&, unsigned long &) const;
590 };
591 
592 class DataNode : public ChunkNode {
593 public:
594   friend class DataChunk;
595   DataNode(const GroveImpl *, const DataChunk *chunk, size_t index);
596   bool same(const BaseNode &node) const;
597   bool same2(const DataNode *node) const;
598   AccessResult nextSibling(NodePtr &ptr) const;
599   AccessResult nextChunkSibling(NodePtr &ptr) const;
600   AccessResult nextChunkAfter(NodePtr &) const;
601   AccessResult siblingsIndex(unsigned long &) const;
602   AccessResult followSiblingRef(unsigned long, NodePtr &) const;
603   AccessResult charChunk(const SdataMapper &, GroveString &) const;
604   bool chunkContains(const Node &) const;
605   bool inChunk(const DataNode *node) const;
606   AccessResult getNonSgml(unsigned long &) const;
607   AccessResult getLocation(Location &) const;
608   void accept(NodeVisitor &visitor);
classDef() const609   const ClassDef &classDef() const { return ClassDef::dataChar; }
610   unsigned long hash() const;
611   static void add(GroveImpl &grove, const DataEvent &event);
612 private:
chunk() const613   const DataChunk *chunk() const {
614     return (const DataChunk *)ChunkNode::chunk();
615   }
616   void reuseFor(const DataChunk *chunk, size_t index);
617   size_t index_;
618 };
619 
620 inline
DataNode(const GroveImpl * grove,const DataChunk * chunk,size_t index)621 DataNode::DataNode(const GroveImpl *grove,
622 		   const DataChunk *chunk, size_t index)
623 : ChunkNode(grove, chunk), index_(index)
624 {
625 }
626 
627 class PiChunk : private CharsChunk {
628   friend class PiNode;
629   AccessResult setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const;
630 };
631 
632 class PrologPiChunk : public PiChunk {
633   AccessResult getFirstSibling(const GroveImpl *, const ::Chunk *&) const;
634 };
635 
636 class EpilogPiChunk : public PiChunk {
637   AccessResult getFirstSibling(const GroveImpl *, const ::Chunk *&) const;
638 };
639 
640 class PiNode : public ChunkNode {
641 public:
PiNode(const GroveImpl * grove,const PiChunk * chunk)642   PiNode(const GroveImpl *grove, const PiChunk *chunk)
643     : ChunkNode(grove, chunk) {}
644   AccessResult getSystemData(GroveString &) const;
getEntityName(GroveString &) const645   AccessResult getEntityName(GroveString &) const{ return accessNull; }
getEntity(NodePtr &) const646   AccessResult getEntity(NodePtr &) const { return accessNull; }
accept(NodeVisitor & visitor)647   void accept(NodeVisitor &visitor) { visitor.pi(*this); }
classDef() const648   const ClassDef &classDef() const { return ClassDef::pi; }
649   static void add(GroveImpl &grove, const PiEvent &);
650 private:
chunk() const651   const PiChunk *chunk() const {
652     return (const PiChunk *)ChunkNode::chunk();
653   }
654 };
655 
656 class EntityRefChunk : public LocChunk {
657 public:
658   const Entity *entity;
after() const659   const Chunk *after() const { return this + 1; }
660 };
661 
662 class EntityRefNode : public ChunkNode {
663 public:
EntityRefNode(const GroveImpl * grove,const EntityRefChunk * chunk)664   EntityRefNode(const GroveImpl *grove, const EntityRefChunk *chunk)
665     : ChunkNode(grove, chunk) { }
666   AccessResult getEntity(NodePtr &) const;
667   AccessResult getEntityName(GroveString &) const;
668 protected:
chunk() const669   const EntityRefChunk *chunk() const {
670     return (const EntityRefChunk *)ChunkNode::chunk();
671   }
672 };
673 
674 class SdataNode;
675 
676 class SdataChunk : private EntityRefChunk {
677   friend class SdataNode;
678   AccessResult setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const;
679 };
680 
681 class SdataNode : public EntityRefNode {
682 public:
SdataNode(const GroveImpl * grove,const SdataChunk * chunk)683   SdataNode(const GroveImpl *grove, const SdataChunk *chunk)
684     : EntityRefNode(grove, chunk) { }
685   AccessResult charChunk(const SdataMapper &, GroveString &) const;
686   AccessResult getSystemData(GroveString &str) const;
accept(NodeVisitor & visitor)687   void accept(NodeVisitor &visitor) { visitor.sdata(*this); }
classDef() const688   const ClassDef &classDef() const { return ClassDef::sdata; }
689   static void add(GroveImpl &grove, const SdataEntityEvent &event);
690 private:
691   Char c_;
692 };
693 
694 class NonSgmlNode;
695 
696 class NonSgmlChunk : public LocChunk {
697 public:
698   Char c;
699   AccessResult setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const;
after() const700   const Chunk *after() const { return this + 1; }
701 };
702 
703 class NonSgmlNode : public ChunkNode {
704 public:
NonSgmlNode(const GroveImpl * grove,const NonSgmlChunk * chunk)705   NonSgmlNode(const GroveImpl *grove, const NonSgmlChunk *chunk)
706     : ChunkNode(grove, chunk) { }
707   AccessResult charChunk(const SdataMapper &, GroveString &) const;
708   AccessResult getNonSgml(unsigned long &) const;
accept(NodeVisitor & visitor)709   void accept(NodeVisitor &visitor) { visitor.nonSgml(*this); }
classDef() const710   const ClassDef &classDef() const { return ClassDef::nonSgml; }
711   static void add(GroveImpl &grove, const NonSgmlCharEvent &event);
712 protected:
chunk() const713   const NonSgmlChunk *chunk() const {
714     return (const NonSgmlChunk *)ChunkNode::chunk();
715   }
716 };
717 
718 class ExternalDataNode;
719 
720 class ExternalDataChunk : private EntityRefChunk {
721   friend class ExternalDataNode;
722   AccessResult setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const;
723 };
724 
725 class ExternalDataNode : public EntityRefNode {
726 public:
ExternalDataNode(const GroveImpl * grove,const ExternalDataChunk * chunk)727   ExternalDataNode(const GroveImpl *grove, const ExternalDataChunk *chunk)
728     : EntityRefNode(grove, chunk) { }
accept(NodeVisitor & visitor)729   void accept(NodeVisitor &visitor) { visitor.externalData(*this); }
classDef() const730   const ClassDef &classDef() const { return ClassDef::externalData; }
731   static void add(GroveImpl &grove, const ExternalDataEntityEvent &event);
732 };
733 
734 class SubdocChunk : private EntityRefChunk {
735   friend class SubdocNode;
736   AccessResult setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const;
737 };
738 
739 class SubdocNode : public EntityRefNode {
740 public:
SubdocNode(const GroveImpl * grove,const SubdocChunk * chunk)741   SubdocNode(const GroveImpl *grove, const SubdocChunk *chunk)
742     : EntityRefNode(grove, chunk) { }
accept(NodeVisitor & visitor)743   void accept(NodeVisitor &visitor) { visitor.subdocument(*this); }
classDef() const744   const ClassDef &classDef() const { return ClassDef::subdocument; }
745   static void add(GroveImpl &grove, const SubdocEntityEvent &event);
746 };
747 
748 class PiEntityChunk : private EntityRefChunk {
749   friend class PiEntityNode;
750   AccessResult setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const;
751 };
752 
753 class PiEntityNode : public EntityRefNode {
754 public:
PiEntityNode(const GroveImpl * grove,const PiEntityChunk * chunk)755   PiEntityNode(const GroveImpl *grove, const PiEntityChunk *chunk)
756     : EntityRefNode(grove, chunk) { }
757   AccessResult getSystemData(GroveString &) const;
accept(NodeVisitor & visitor)758   void accept(NodeVisitor &visitor) { visitor.pi(*this); }
classDef() const759   const ClassDef &classDef() const { return ClassDef::pi; }
760   static void add(GroveImpl &grove,  const Entity *, const Location &);
761 };
762 
763 struct AttributeOrigin {
764   virtual const AttributeDefinitionList *attDefList() const = 0;
765   virtual const AttributeValue *
766     attributeValue(size_t attIndex, const GroveImpl &grove) const = 0;
767   virtual AccessResult
768     setNodePtrAttributeOrigin(NodePtr &, const BaseNode *) const = 0;
769   virtual Node *makeCdataAttributeValueNode(const GroveImpl *grove,
770 					    const AttributeValue *value,
771 					    size_t attIndex,
772 					    const TextIter &iter,
773 					    size_t charIndex = 0) const = 0;
774   virtual Node *makeAttributeValueTokenNode(const GroveImpl *grove,
775 					    const TokenizedAttributeValue *value,
776 					    size_t attIndex,
777 					    size_t tokenIndex) const = 0;
778   virtual Node *makeAttributeAsgnNode(const GroveImpl *grove,
779 				      size_t attIndex) const = 0;
780   virtual const void *attributeOriginId() const = 0;
781 };
782 
783 class ElementAttributeOrigin : public virtual AttributeOrigin {
784 public:
785   ElementAttributeOrigin(const ElementChunk *);
786   const AttributeDefinitionList *attDefList() const;
787   const AttributeValue *
788     attributeValue(size_t attIndex, const GroveImpl &grove) const;
789   AccessResult setNodePtrAttributeOrigin(NodePtr &, const BaseNode *) const;
790   Node *makeCdataAttributeValueNode(const GroveImpl *grove,
791 				    const AttributeValue *value,
792 				    size_t attIndex,
793 				    const TextIter &iter,
794 				    size_t charIndex) const;
795   Node *makeAttributeValueTokenNode(const GroveImpl *grove,
796 				    const TokenizedAttributeValue *value,
797 				    size_t attIndex,
798 				    size_t tokenIndex) const;
799   Node *makeAttributeAsgnNode(const GroveImpl *grove,
800 			      size_t attIndex) const;
801   const void *attributeOriginId() const;
802 private:
803   const ElementChunk *chunk_;
804 };
805 
806 class EntityAttributeOrigin : public virtual AttributeOrigin {
807 public:
808   EntityAttributeOrigin(const ExternalDataEntity *);
809   const AttributeDefinitionList *attDefList() const;
810   const AttributeValue *
811     attributeValue(size_t attIndex, const GroveImpl &grove) const;
812   AccessResult setNodePtrAttributeOrigin(NodePtr &, const BaseNode *) const;
813   Node *makeCdataAttributeValueNode(const GroveImpl *grove,
814 				    const AttributeValue *value,
815 				    size_t attIndex,
816 				    const TextIter &iter,
817 				    size_t charIndex) const;
818   Node *makeAttributeValueTokenNode(const GroveImpl *grove,
819 				    const TokenizedAttributeValue *value,
820 				    size_t attIndex,
821 				    size_t tokenIndex) const;
822   Node *makeAttributeAsgnNode(const GroveImpl *grove,
823 			      size_t attIndex) const;
824   const void *attributeOriginId() const;
825 private:
826   const ExternalDataEntity *entity_;
827 };
828 
829 
830 class AttributeAsgnNode : public BaseNode, public virtual AttributeOrigin {
831 public:
832   AttributeAsgnNode(const GroveImpl *grove, size_t attIndex);
833   AccessResult getOrigin(NodePtr &ptr) const;
834   AccessResult getName(GroveString &str) const;
835   AccessResult getImplied(bool &implied) const;
836   AccessResult getValue(NodeListPtr &ptr) const;
837   AccessResult children(NodeListPtr &ptr) const;
838   AccessResult firstChild(NodePtr &ptr) const;
839   AccessResult nextChunkSibling(NodePtr &ptr) const;
840   AccessResult followSiblingRef(unsigned long, NodePtr &) const;
841   AccessResult firstSibling(NodePtr &) const;
842   AccessResult siblingsIndex(unsigned long &) const;
843   AccessResult getTokenSep(Char &) const;
844   AccessResult tokens(GroveString &) const;
845   void accept(NodeVisitor &visitor);
classDef() const846   const ClassDef &classDef() const { return ClassDef::attributeAssignment; }
getOriginToSubnodeRelPropertyName(ComponentName::Id & name) const847   AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
848     name = ComponentName::idAttributes;
849     return accessOK;
850   }
851   bool same(const BaseNode &node) const;
852   bool same2(const AttributeAsgnNode *node) const;
853   unsigned long hash() const;
854 private:
855   size_t attIndex_;
856 };
857 
858 class ElementAttributeAsgnNode
859 : public AttributeAsgnNode, public ElementAttributeOrigin {
860 public:
861   ElementAttributeAsgnNode(const GroveImpl *grove, size_t attIndex,
862 			   const ElementChunk *);
863 };
864 
865 class EntityAttributeAsgnNode
866 : public AttributeAsgnNode, public EntityAttributeOrigin {
867 public:
868   EntityAttributeAsgnNode(const GroveImpl *grove, size_t attIndex,
869 			   const ExternalDataEntity *);
870 };
871 
872 class AttributeValueTokenNode
873 : public BaseNode, public virtual AttributeOrigin {
874 public:
875   AttributeValueTokenNode(const GroveImpl *grove,
876 			  const TokenizedAttributeValue *value,
877 			  size_t attIndex, size_t tokenIndex);
878   AccessResult getParent(NodePtr &ptr) const;
879   AccessResult nextChunkSibling(NodePtr &ptr) const;
880   AccessResult followSiblingRef(unsigned long, NodePtr &ptr) const;
881   AccessResult firstSibling(NodePtr &) const;
882   AccessResult siblingsIndex(unsigned long &) const;
883   AccessResult getToken(GroveString &str) const;
884   AccessResult getEntity(NodePtr &ptr) const;
885   AccessResult getNotation(NodePtr &ptr) const;
886   AccessResult getReferent(NodePtr &ptr) const;
887   AccessResult getLocation(Location &) const;
888   void accept(NodeVisitor &visitor);
classDef() const889   const ClassDef &classDef() const { return ClassDef::attributeValueToken; }
getOriginToSubnodeRelPropertyName(ComponentName::Id & name) const890   AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
891     name = ComponentName::idValue;
892     return accessOK;
893   }
894   bool same(const BaseNode &node) const;
895   bool same2(const AttributeValueTokenNode *node) const;
896   unsigned long hash() const;
897 private:
898   const TokenizedAttributeValue *value_;
899   size_t attIndex_;
900   size_t tokenIndex_;
901 };
902 
903 class ElementAttributeValueTokenNode
904 : public AttributeValueTokenNode, public ElementAttributeOrigin {
905 public:
906   ElementAttributeValueTokenNode(const GroveImpl *grove,
907 				 const TokenizedAttributeValue *value,
908 				 size_t attIndex,
909 				 size_t tokenIndex,
910 				 const ElementChunk *);
911 };
912 
913 class EntityAttributeValueTokenNode
914 : public AttributeValueTokenNode, public EntityAttributeOrigin {
915 public:
916   EntityAttributeValueTokenNode(const GroveImpl *grove,
917 				const TokenizedAttributeValue *value,
918 				size_t attIndex,
919 				size_t tokenIndex,
920 				const ExternalDataEntity *);
921 };
922 
923 class CdataAttributeValueNode
924 : public BaseNode, public virtual AttributeOrigin {
925 public:
926   static bool skipBoring(TextIter &iter);
927   CdataAttributeValueNode(const GroveImpl *grove,
928 			  const AttributeValue *value,
929 			  size_t attIndex,
930 			  const TextIter &iter,
931 			  size_t charIndex);
932   AccessResult getParent(NodePtr &ptr) const;
933   AccessResult charChunk(const SdataMapper &, GroveString &) const;
934   bool chunkContains(const Node &) const;
935   bool inChunk(const CdataAttributeValueNode *) const;
936   AccessResult getEntity(NodePtr &) const;
937   AccessResult getEntityName(GroveString &) const;
938   AccessResult getSystemData(GroveString &str) const;
939   AccessResult nextSibling(NodePtr &ptr) const;
940   AccessResult nextChunkSibling(NodePtr &ptr) const;
941   AccessResult firstSibling(NodePtr &) const;
942   AccessResult siblingsIndex(unsigned long &) const;
943   AccessResult getLocation(Location &) const;
944   void accept(NodeVisitor &visitor);
945   const ClassDef &classDef() const;
getOriginToSubnodeRelPropertyName(ComponentName::Id & name) const946   AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
947     name = ComponentName::idValue;
948     return accessOK;
949   }
950   bool same(const BaseNode &node) const;
951   bool same2(const CdataAttributeValueNode *node) const;
952   unsigned long hash() const;
953 private:
954   const AttributeValue *value_;
955   size_t attIndex_;
956   TextIter iter_; // must be valid
957   size_t charIndex_;
958   Char c_;
959 };
960 
961 class ElementCdataAttributeValueNode
962 : public CdataAttributeValueNode, public ElementAttributeOrigin {
963 public:
964   ElementCdataAttributeValueNode(const GroveImpl *grove,
965 				 const AttributeValue *value,
966 				 size_t attIndex,
967 				 const TextIter &iter,
968 				 size_t charIndex,
969 				 const ElementChunk *);
970 };
971 
972 class EntityCdataAttributeValueNode
973 : public CdataAttributeValueNode, public EntityAttributeOrigin {
974 public:
975   EntityCdataAttributeValueNode(const GroveImpl *grove,
976 				const AttributeValue *value,
977 				size_t attIndex,
978 				const TextIter &iter,
979 				size_t charIndex,
980 				const ExternalDataEntity *);
981 };
982 
983 class EntityNode : public BaseNode {
984 public:
985   EntityNode(const GroveImpl *grove, const Entity *entity);
986   AccessResult getOrigin(NodePtr &ptr) const;
987   AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &) const;
988   AccessResult getName(GroveString &str) const;
989   AccessResult getExternalId(NodePtr &ptr) const;
990   AccessResult getNotation(NodePtr &) const;
991   AccessResult getNotationName(GroveString &) const;
992   AccessResult getText(GroveString &) const;
993   AccessResult getEntityType(EntityType &) const;
994   AccessResult getDefaulted(bool &) const;
995   AccessResult getAttributes(NamedNodeListPtr &) const;
996   AccessResult attributeRef(unsigned long i, NodePtr &ptr) const;
997   AccessResult getLocation(Location &) const;
998   bool same(const BaseNode &) const;
999   bool same2(const EntityNode *) const;
1000   void accept(NodeVisitor &);
classDef() const1001   const ClassDef &classDef() const { return ClassDef::entity; }
1002   unsigned long hash() const;
1003 private:
1004   const Entity *entity_;
1005 };
1006 
1007 class NotationNode : public BaseNode {
1008 public:
1009   NotationNode(const GroveImpl *grove, const Notation *notation);
1010   AccessResult getOrigin(NodePtr &ptr) const;
getOriginToSubnodeRelPropertyName(ComponentName::Id & name) const1011   AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
1012     name = ComponentName::idNotations;
1013     return accessOK;
1014   }
1015   AccessResult getName(GroveString &str) const;
1016   AccessResult getExternalId(NodePtr &ptr) const;
1017   bool same(const BaseNode &) const;
1018   bool same2(const NotationNode *) const;
1019   AccessResult getLocation(Location &) const;
1020   void accept(NodeVisitor &);
classDef() const1021   const ClassDef &classDef() const { return ClassDef::notation; }
1022   unsigned long hash() const;
1023 private:
1024   const Notation *notation_;
1025 };
1026 
1027 class ExternalIdNode : public BaseNode {
1028 public:
1029   ExternalIdNode(const GroveImpl *grove);
1030   virtual const ExternalId &externalId() const = 0;
1031   AccessResult getPublicId(GroveString &) const;
1032   AccessResult getSystemId(GroveString &) const;
1033   AccessResult getGeneratedSystemId(GroveString &) const;
1034   void accept(NodeVisitor &);
classDef() const1035   const ClassDef &classDef() const { return ClassDef::externalId; }
getOriginToSubnodeRelPropertyName(ComponentName::Id & name) const1036   AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
1037     name = ComponentName::idExternalId;
1038     return accessOK;
1039   }
1040   bool same(const BaseNode &) const;
1041   bool same2(const ExternalIdNode *) const;
1042 };
1043 
1044 class EntityExternalIdNode : public ExternalIdNode {
1045 public:
1046   EntityExternalIdNode(const GroveImpl *grove,
1047 		       const ExternalEntity *entity);
1048   const ExternalId &externalId() const;
1049   AccessResult getOrigin(NodePtr &ptr) const;
1050   unsigned long hash() const;
1051 private:
1052   const ExternalEntity *entity_;
1053 };
1054 
1055 class NotationExternalIdNode : public ExternalIdNode {
1056 public:
1057   NotationExternalIdNode(const GroveImpl *grove,
1058 			 const Notation *notation);
1059   const ExternalId &externalId() const;
1060   AccessResult getOrigin(NodePtr &ptr) const;
1061   unsigned long hash() const;
1062 private:
1063   const Notation *notation_;
1064 };
1065 
1066 class DocumentTypeNode : public BaseNode {
1067 public:
1068   DocumentTypeNode(const GroveImpl *grove, const Dtd *);
1069   AccessResult getName(GroveString &) const;
1070   AccessResult getGoverning(bool &) const;
1071   AccessResult getGeneralEntities(NamedNodeListPtr &) const;
1072   AccessResult getNotations(NamedNodeListPtr &) const;
1073   AccessResult getOrigin(NodePtr &) const;
getOriginToSubnodeRelPropertyName(ComponentName::Id & name) const1074   AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
1075     name = ComponentName::idDoctypesAndLinktypes;
1076     return accessOK;
1077   }
1078   AccessResult nextChunkSibling(NodePtr &) const;
1079   void accept(NodeVisitor &);
classDef() const1080   const ClassDef &classDef() const { return ClassDef::documentType; }
1081   bool same(const BaseNode &) const;
1082   bool same2(const DocumentTypeNode *) const;
1083 private:
1084   const Dtd *dtd_;
1085 };
1086 
1087 class SgmlConstantsNode : public BaseNode {
1088 public:
1089   SgmlConstantsNode(const GroveImpl *);
1090   AccessResult getOrigin(NodePtr &) const;
1091   void accept(NodeVisitor &);
classDef() const1092   const ClassDef &classDef() const { return ClassDef::sgmlConstants; }
getOriginToSubnodeRelPropertyName(ComponentName::Id & name) const1093   AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
1094     name = ComponentName::idSgmlConstants;
1095     return accessOK;
1096   }
1097   bool same(const BaseNode &) const;
1098   bool same2(const SgmlConstantsNode *) const;
1099 };
1100 
1101 class MessageNode : public BaseNode {
1102 public:
1103   MessageNode(const GroveImpl *, const MessageItem *);
1104   AccessResult getOrigin(NodePtr &) const;
getOriginToSubnodeRelPropertyName(ComponentName::Id & name) const1105   AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
1106     name = ComponentName::noId;
1107     return accessOK;
1108   }
1109   AccessResult nextChunkSibling(NodePtr &) const;
1110   AccessResult firstSibling(NodePtr &) const;
1111   AccessResult siblingsIndex(unsigned long &) const;
1112   void accept(NodeVisitor &);
classDef() const1113   const ClassDef &classDef() const { return ClassDef::message; }
1114   bool same(const BaseNode &) const;
1115   bool same2(const MessageNode *) const;
1116   AccessResult getLocation(Location &) const;
1117   AccessResult getText(GroveString &) const;
1118   AccessResult getSeverity(Severity &) const;
1119 private:
1120   const MessageItem *item_;
1121 };
1122 
1123 class BaseNodeList : public NodeList {
1124 public:
BaseNodeList()1125   BaseNodeList() : refCount_(0) { }
~BaseNodeList()1126   virtual ~BaseNodeList() { }
addRef()1127   void addRef() { ++refCount_; }
canReuse(NodeListPtr & ptr) const1128   bool canReuse(NodeListPtr &ptr) const {
1129     const NodeList *tem = &*ptr;
1130     return tem == this && refCount_ == 1;
1131   }
release()1132   void release() {
1133     ASSERT(refCount_ != 0);
1134     if (--refCount_ == 0) delete this;
1135   }
first(NodePtr &) const1136   AccessResult first(NodePtr &) const { return accessNull; }
rest(NodeListPtr & ptr) const1137   AccessResult rest(NodeListPtr &ptr) const { return chunkRest(ptr); }
chunkRest(NodeListPtr &) const1138   AccessResult chunkRest(NodeListPtr &) const { return accessNull; }
1139 private:
1140   unsigned refCount_;
1141 };
1142 
1143 class SiblingNodeList : public BaseNodeList {
1144 public:
SiblingNodeList(const NodePtr & first)1145   SiblingNodeList(const NodePtr &first) : first_(first) { }
first(NodePtr & ptr) const1146   AccessResult first(NodePtr &ptr) const {
1147     ptr = first_;
1148     return accessOK;
1149   }
rest(NodeListPtr & ptr) const1150   AccessResult rest(NodeListPtr &ptr) const {
1151     AccessResult ret;
1152     if (canReuse(ptr)) {
1153       ret = ((SiblingNodeList *)this)->first_.assignNextSibling();
1154       if (ret == accessOK)
1155 	return ret;
1156     }
1157     else {
1158       NodePtr next;
1159       ret = first_->nextSibling(next);
1160       if (ret == accessOK) {
1161 	ptr.assign(new SiblingNodeList(next));
1162 	return ret;
1163       }
1164     }
1165     if (ret == accessNull) {
1166       ptr.assign(new BaseNodeList);
1167       return accessOK;
1168     }
1169     return ret;
1170   }
chunkRest(NodeListPtr & ptr) const1171   AccessResult chunkRest(NodeListPtr &ptr) const {
1172     AccessResult ret;
1173     if (canReuse(ptr)) {
1174       ret = ((SiblingNodeList *)this)->first_.assignNextChunkSibling();
1175       if (ret == accessOK)
1176 	return ret;
1177     }
1178     else {
1179       NodePtr next;
1180       ret = first_->nextChunkSibling(next);
1181       if (ret == accessOK) {
1182 	ptr.assign(new SiblingNodeList(next));
1183 	return ret;
1184       }
1185     }
1186     if (ret == accessNull) {
1187       ptr.assign(new BaseNodeList);
1188       return accessOK;
1189     }
1190     return ret;
1191   }
ref(unsigned long i,NodePtr & ptr) const1192   AccessResult ref(unsigned long i, NodePtr &ptr) const {
1193     if (i == 0) {
1194       ptr = first_;
1195       return accessOK;
1196     }
1197     return first_->followSiblingRef(i - 1, ptr);
1198   }
1199 private:
1200   NodePtr first_; // never null
1201 };
1202 
1203 class BaseNamedNodeList : public NamedNodeList {
1204 public:
BaseNamedNodeList(const GroveImpl * grove,const SubstTable<Char> * substTable)1205   BaseNamedNodeList(const GroveImpl *grove,
1206 		    const SubstTable<Char> *substTable)
1207   : grove_(grove), substTable_(substTable), refCount_(0) { }
~BaseNamedNodeList()1208   virtual ~BaseNamedNodeList() { }
addRef()1209   void addRef() { ++refCount_; }
canReuse(NamedNodeListPtr & ptr) const1210   bool canReuse(NamedNodeListPtr &ptr) const {
1211     const NamedNodeList *tem = &*ptr;
1212     return tem == this && refCount_ == 1;
1213   }
release()1214   void release() {
1215     ASSERT(refCount_ != 0);
1216     if (--refCount_ == 0) delete this;
1217   }
normalize(Char * s,size_t n) const1218   size_t normalize(Char *s, size_t n) const {
1219     if (substTable_) {
1220       for (size_t i = 0; i < n; i++)
1221 	substTable_->subst(s[i]);
1222     }
1223     return n;
1224   }
grove() const1225   const GroveImpl *grove() const { return grove_; }
namedNode(GroveString str,NodePtr & node) const1226   AccessResult namedNode(GroveString str, NodePtr &node) const {
1227     StringC tem(str.data(), str.size());
1228     normalize(&tem[0], tem.size());
1229     return namedNodeU(tem, node);
1230   }
1231   virtual AccessResult namedNodeU(const StringC &, NodePtr &) const = 0;
1232 private:
1233   GroveImplPtr grove_;
1234   const SubstTable<Char> *substTable_;
1235   unsigned refCount_;
1236 };
1237 
1238 class AttributesNamedNodeList
1239 : public BaseNamedNodeList, public virtual AttributeOrigin {
1240 public:
AttributesNamedNodeList(const GroveImpl * grove)1241   AttributesNamedNodeList(const GroveImpl *grove)
1242    : BaseNamedNodeList(grove, grove->generalSubstTable()) { }
1243   NodeListPtr nodeList() const;
1244   AccessResult namedNodeU(const StringC &, NodePtr &) const;
type() const1245   Type type() const { return attributes; }
1246 };
1247 
1248 class ElementAttributesNamedNodeList
1249 : public AttributesNamedNodeList, public ElementAttributeOrigin {
1250 public:
ElementAttributesNamedNodeList(const GroveImpl * grove,const ElementChunk * chunk)1251   ElementAttributesNamedNodeList(const GroveImpl *grove,
1252 				 const ElementChunk *chunk)
1253    : AttributesNamedNodeList(grove), ElementAttributeOrigin(chunk) { }
1254 };
1255 
1256 class EntityAttributesNamedNodeList
1257 : public AttributesNamedNodeList, public EntityAttributeOrigin {
1258 public:
EntityAttributesNamedNodeList(const GroveImpl * grove,const ExternalDataEntity * entity)1259   EntityAttributesNamedNodeList(const GroveImpl *grove,
1260 				const ExternalDataEntity *entity)
1261    : AttributesNamedNodeList(grove), EntityAttributeOrigin(entity) { }
1262 };
1263 
1264 class ElementsNamedNodeList : public BaseNamedNodeList {
1265 public:
ElementsNamedNodeList(const GroveImpl * grove)1266   ElementsNamedNodeList(const GroveImpl *grove)
1267     : BaseNamedNodeList(grove, grove->generalSubstTable()) { }
1268   NodeListPtr nodeList() const;
1269   AccessResult namedNodeU(const StringC &, NodePtr &) const;
type() const1270   Type type() const { return elements; }
1271 };
1272 
1273 class DocEntitiesNamedNodeList : public BaseNamedNodeList {
1274 public:
DocEntitiesNamedNodeList(const GroveImpl * grove)1275   DocEntitiesNamedNodeList(const GroveImpl *grove)
1276    : BaseNamedNodeList(grove, grove->entitySubstTable()) { }
1277   NodeListPtr nodeList() const;
1278   AccessResult namedNodeU(const StringC &, NodePtr &) const;
type() const1279   Type type() const { return entities; }
1280 };
1281 
1282 class DefaultedEntitiesNamedNodeList : public BaseNamedNodeList {
1283 public:
DefaultedEntitiesNamedNodeList(const GroveImpl * grove)1284   DefaultedEntitiesNamedNodeList(const GroveImpl *grove)
1285    : BaseNamedNodeList(grove, grove->entitySubstTable()) { }
1286   NodeListPtr nodeList() const;
1287   AccessResult namedNodeU(const StringC &, NodePtr &) const;
type() const1288   Type type() const { return entities; }
1289 };
1290 
1291 class GeneralEntitiesNamedNodeList : public BaseNamedNodeList {
1292 public:
1293   GeneralEntitiesNamedNodeList(const GroveImpl *, const Dtd *);
1294   NodeListPtr nodeList() const;
1295   AccessResult namedNodeU(const StringC &, NodePtr &) const;
type() const1296   Type type() const { return entities; }
1297 private:
1298   const Dtd *dtd_;
1299 };
1300 
1301 class NotationsNamedNodeList : public BaseNamedNodeList {
1302 public:
1303   NotationsNamedNodeList(const GroveImpl *, const Dtd *);
1304   NodeListPtr nodeList() const;
1305   AccessResult namedNodeU(const StringC &, NodePtr &) const;
type() const1306   Type type() const { return notations; }
1307 private:
1308   const Dtd *dtd_;
1309 };
1310 
1311 class DoctypesAndLinktypesNamedNodeList : public BaseNamedNodeList {
1312 public:
1313   DoctypesAndLinktypesNamedNodeList(const GroveImpl *);
1314   NodeListPtr nodeList() const;
1315   AccessResult namedNodeU(const StringC &, NodePtr &) const;
type() const1316   Type type() const { return doctypesAndLinktypes; }
1317 };
1318 
1319 class ElementsNodeList : public BaseNodeList {
1320 public:
1321   ElementsNodeList(const GroveImpl *grove,
1322                    const Chunk *head);
1323   AccessResult first(NodePtr &) const;
1324   AccessResult chunkRest(NodeListPtr &) const;
1325 public:
1326   GroveImplPtr grove_;
1327   const Chunk *first_;
1328 };
1329 
1330 class EntitiesNodeList : public BaseNodeList {
1331 public:
1332   EntitiesNodeList(const GroveImpl *grove,
1333 		   const Dtd::ConstEntityIter &iter);
1334   AccessResult first(NodePtr &) const;
1335   AccessResult chunkRest(NodeListPtr &) const;
1336 protected:
grove() const1337   const GroveImpl *grove() const { return grove_; }
1338 public:
1339   GroveImplPtr grove_;
1340   Dtd::ConstEntityIter iter_;
1341 };
1342 
1343 class DocEntitiesNodeList : public EntitiesNodeList {
1344 public:
1345   DocEntitiesNodeList(const GroveImpl *grove);
1346   AccessResult first(NodePtr &) const;
1347   AccessResult chunkRest(NodeListPtr &) const;
1348 };
1349 
1350 class NotationsNodeList : public BaseNodeList {
1351 public:
1352   NotationsNodeList(const GroveImpl *grove,
1353                     const Dtd::ConstNotationIter &iter);
1354   AccessResult first(NodePtr &) const;
1355   AccessResult chunkRest(NodeListPtr &) const;
1356 public:
1357   GroveImplPtr grove_;
1358   Dtd::ConstNotationIter iter_;
1359 };
1360 
1361 inline
waitForMoreNodes() const1362 Boolean GroveImpl::waitForMoreNodes() const
1363 {
1364   if (blockingAccess)
1365     return moreNodesCondition_.wait();
1366   else
1367     return 0;
1368 }
1369 
1370 inline
pulse()1371 void GroveImpl::pulse()
1372 {
1373   moreNodesCondition_.pulse();
1374 }
1375 
1376 inline
maybePulse()1377 void GroveImpl::maybePulse()
1378 {
1379   // Once we've had (2^n)*(2^10) events, only pulse every (2^n)th event.
1380   // Up to a limit of n == 8.
1381   // This reduces the overhead of pulsing to negligible levels on WinNT.
1382   if ((++nEvents_ & ~(~unsigned(0) << pulseStep_)) == 0) {
1383     pulse();
1384     if (pulseStep_ < 8 && nEvents_ > (1 << (pulseStep_ + 10)))
1385       pulseStep_++;
1386   }
1387 }
1388 
1389 inline
appendSibling(Chunk * chunk)1390 void GroveImpl::appendSibling(Chunk *chunk)
1391 {
1392   if (pendingData_) {
1393     if (tailPtr_) {
1394       // Must set completeLimit_ before setting tailPtr_.
1395       completeLimit_ = pendingData_->after();
1396       *tailPtr_ = pendingData_;
1397       tailPtr_ = 0;
1398     }
1399     pendingData_ = 0;
1400   }
1401   // Must set origin before advancing completeLimit_.
1402   chunk->origin = origin_;
1403   // Must advance completeLimit_ before setting tailPtr_.
1404   completeLimit_ = freePtr_;
1405   if (tailPtr_) {
1406     *tailPtr_ = chunk;
1407     tailPtr_ = 0;
1408   }
1409   pendingData_ = 0;
1410   maybePulse();
1411 }
1412 
1413 inline
appendSibling(DataChunk * chunk)1414 void GroveImpl::appendSibling(DataChunk *chunk)
1415 {
1416   // Since we might extend this DataChunk, it's
1417   // not safe to set completeLimit_ to after this chunk yet.
1418   // This means we can't yet set tailPtr_.
1419   if (pendingData_) {
1420     // Must set completeLimit_ before setting tailPtr_.
1421     completeLimit_ = pendingData_->after();
1422     if (tailPtr_) {
1423       *tailPtr_ = pendingData_;
1424       tailPtr_ = 0;
1425     }
1426   }
1427   chunk->origin = origin_;
1428   pendingData_ = chunk;
1429   maybePulse();
1430 }
1431 
1432 inline
push(ElementChunk * chunk,Boolean hasId)1433 void GroveImpl::push(ElementChunk *chunk, Boolean hasId)
1434 {
1435   if (pendingData_) {
1436     if (tailPtr_) {
1437       // Must set completeLimit_ before setting tailPtr_.
1438       completeLimit_ = pendingData_->after();
1439       *tailPtr_ = pendingData_;
1440       tailPtr_ = 0;
1441     }
1442     pendingData_ = 0;
1443   }
1444   chunk->elementIndex = nElements_++;
1445   chunk->origin = origin_;
1446   // Must set origin_ to chunk before advancing completeLimit_
1447   // otherwise thread would look at element and
1448   // maybeMoreSiblings() would return false.
1449   // Must advance completeLimit_ before setting tailPtr_,
1450   // otherwise tailPtr_ would be beyond completeLimit_.
1451   origin_ = chunk;
1452   completeLimit_ = freePtr_;
1453   // Allow for the possibility of invalid documents with elements
1454   // after the document element.
1455   if ((const Chunk *)chunk->origin == root_ && root_->documentElement == 0)
1456     root_->documentElement = chunk;
1457   else if (tailPtr_) {
1458     *tailPtr_ = chunk;
1459     tailPtr_ = 0;
1460   }
1461   if (hasId) {
1462     Mutex::Lock lock(mutexPtr_);
1463     idTable_.insert(chunk);
1464   }
1465   maybePulse();
1466 }
1467 
1468 inline
pop()1469 void GroveImpl::pop()
1470 {
1471   if (pendingData_) {
1472     // Must set completeLimit_ before setting tailPtr_.
1473     completeLimit_ = pendingData_->after();
1474     if (tailPtr_) {
1475       *tailPtr_ = pendingData_;
1476       tailPtr_ = 0;
1477     }
1478     pendingData_ = 0;
1479   }
1480   tailPtr_ = &origin_->nextSibling;
1481   origin_ = origin_->origin;
1482   if ((const Chunk *)origin_ == root_)
1483     finishDocumentElement();
1484   maybePulse();
1485 }
1486 
1487 inline
haveRootOrigin()1488 Boolean GroveImpl::haveRootOrigin()
1489 {
1490   return (const Chunk *)origin_ == root_;
1491 }
1492 
1493 inline
setDtd(const ConstPtr<Dtd> & dtd)1494 void GroveImpl::setDtd(const ConstPtr<Dtd> &dtd)
1495 {
1496   dtd_ = dtd;
1497   hasDefaultEntity_ = !dtd_->defaultEntity().isNull();
1498   finishProlog();
1499   pulse();
1500 }
1501 
1502 inline
lookupElement(const StringC & id) const1503 const ElementChunk *GroveImpl::lookupElement(const StringC &id) const
1504 {
1505   Mutex::Lock lock(mutexPtr_);
1506   return idTable_.lookup(id);
1507 }
1508 
1509 inline
elementIter() const1510 GroveImpl::ElementIter GroveImpl::elementIter() const
1511 {
1512   ASSERT(complete());
1513   return ElementIter(idTable_);
1514 }
1515 
1516 inline
maybeMoreSiblings(const ParentChunk * chunk) const1517 Boolean GroveImpl::maybeMoreSiblings(const ParentChunk *chunk) const
1518 {
1519   return (complete_
1520           ? chunk->nextSibling != 0
1521 	  : (origin_ == chunk
1522 	      || &chunk->nextSibling == tailPtr_
1523 	      || maybeMoreSiblings1(chunk)));
1524 }
1525 
1526 inline
allocChunk(size_t n)1527 void *GroveImpl::allocChunk(size_t n)
1528 {
1529   nChunksSinceLocOrigin_++;
1530   if (n <= nFree_) {
1531     void *p = freePtr_;
1532     freePtr_ += n;
1533     nFree_ -= n;
1534     return p;
1535   }
1536   else
1537     return allocFinish(n);
1538 }
1539 
1540 inline
setLocOrigin(const ConstPtr<Origin> & locOrigin)1541 void GroveImpl::setLocOrigin(const ConstPtr<Origin> &locOrigin)
1542 {
1543   if (locOrigin.pointer() != currentLocOrigin_
1544       || nChunksSinceLocOrigin_ >= maxChunksWithoutLocOrigin)
1545     storeLocOrigin(locOrigin);
1546 }
1547 
1548 inline
appendMessage(MessageItem * item)1549 void GroveImpl::appendMessage(MessageItem *item)
1550 {
1551   *messageListTailP_ = item;
1552   messageListTailP_ = item->nextP();
1553   pulse();
1554 }
1555 
1556 inline
add(GroveImpl & grove,const StartElementEvent & event)1557 void ElementNode::add(GroveImpl &grove, const StartElementEvent &event)
1558 {
1559   grove.setLocOrigin(event.location().origin());
1560   ElementChunk *chunk;
1561   const AttributeList &atts = event.attributes();
1562   Boolean hasId;
1563   if (atts.nSpec() == 0 && !atts.anyCurrent()) {
1564     void *mem = grove.allocChunk(sizeof(ElementChunk));
1565     if (event.included())
1566       chunk = new (mem) IncludedElementChunk;
1567     else
1568       chunk = new (mem) ElementChunk;
1569     hasId = 0;
1570   }
1571   else
1572     chunk = makeAttElementChunk(grove, event, hasId);
1573   chunk->type = event.elementType();
1574   chunk->locIndex = event.location().index();
1575   grove.push(chunk, hasId);
1576 }
1577 
1578 // We duplicate ChunkNode::nextChunkSibling to take advantage
1579 // of Node reuse (via setNodePtrFirst(NodePtr &, const DataNode *).
1580 inline
nextChunkSibling(NodePtr & ptr) const1581 AccessResult DataNode::nextChunkSibling(NodePtr &ptr) const
1582 {
1583   // The forwarding chunk has origin = 0, so it will stop
1584   // the iteration before after() can return 0.
1585   const Chunk *p = chunk_->after();
1586   while (p == grove()->completeLimit())
1587     if (!grove()->waitForMoreNodes())
1588       return accessTimeout;
1589   if (p->origin != chunk_->origin)
1590     return accessNull;
1591   return p->setNodePtrFirst(ptr, this);
1592 }
1593 
1594 inline
reuseFor(const DataChunk * chunk,size_t index)1595 void DataNode::reuseFor(const DataChunk *chunk, size_t index)
1596 {
1597   chunk_ = chunk;
1598   index_ = index;
1599 }
1600 
1601 inline
add(GroveImpl & grove,const DataEvent & event)1602 void DataNode::add(GroveImpl &grove, const DataEvent &event)
1603 {
1604   size_t dataLen = event.dataLength();
1605   if (dataLen) {
1606    DataChunk *chunk = grove.pendingData();
1607    if (chunk
1608        && event.location().origin().pointer() == grove.currentLocOrigin()
1609        && event.location().index() == chunk->locIndex + chunk->size
1610        && grove.tryExtend(CharsChunk::allocSize(chunk->size + dataLen)
1611                           - CharsChunk::allocSize(chunk->size))) {
1612      memcpy((Char *)(chunk + 1) + chunk->size,
1613 	    event.data(),
1614 	    dataLen * sizeof(Char));
1615      chunk->size += dataLen;
1616    }
1617    else {
1618      grove.setLocOrigin(event.location().origin());
1619      chunk = new (grove.allocChunk(CharsChunk::allocSize(dataLen))) DataChunk;
1620      chunk->size = dataLen;
1621      chunk->locIndex = event.location().index();
1622      memcpy(chunk + 1, event.data(), dataLen * sizeof(Char));
1623      grove.appendSibling(chunk);
1624    }
1625  }
1626 }
1627 
GroveBuilderMessageEventHandler(unsigned groveIndex,Messenger * mgr,MessageFormatter * msgFmt)1628 GroveBuilderMessageEventHandler::GroveBuilderMessageEventHandler(unsigned groveIndex,
1629 								 Messenger *mgr,
1630 								 MessageFormatter *msgFmt)
1631 : mgr_(mgr), grove_(new GroveImpl(groveIndex)), msgFmt_(msgFmt)
1632 {
1633   grove_->addRef();
1634 }
1635 
~GroveBuilderMessageEventHandler()1636 GroveBuilderMessageEventHandler::~GroveBuilderMessageEventHandler()
1637 {
1638   grove_->setComplete();
1639   grove_->release();
1640 }
1641 
makeInitialRoot(NodePtr & root)1642 void GroveBuilderMessageEventHandler::makeInitialRoot(NodePtr &root)
1643 {
1644   root.assign(new SgmlDocumentNode(grove_, grove_->root()));
1645 }
1646 
message(MessageEvent * event)1647 void GroveBuilderMessageEventHandler::message(MessageEvent *event)
1648 {
1649   mgr_->dispatchMessage(event->message());
1650   const Message &msg = event->message();
1651   StrOutputCharStream os;
1652   msgFmt_->formatMessage(*msg.type, msg.args, os);
1653   StringC tem;
1654   os.extractString(tem);
1655   Node::Severity severity;
1656   switch (msg.type->severity()) {
1657   case MessageType::info:
1658     severity = Node::info;
1659     break;
1660   case MessageType::warning:
1661     severity = Node::warning;
1662     break;
1663   default:
1664     severity = Node::error;
1665     break;
1666   }
1667   grove_->appendMessage(new MessageItem(severity, tem, msg.loc));
1668   if (!msg.auxLoc.origin().isNull()) {
1669     msgFmt_->formatMessage(msg.type->auxFragment(), msg.args, os);
1670     os.extractString(tem);
1671     grove_->appendMessage(new MessageItem(Node::info, tem, msg.auxLoc));
1672   }
1673   ErrorCountEventHandler::message(event);
1674 }
1675 
sgmlDecl(SgmlDeclEvent * event)1676 void GroveBuilderMessageEventHandler::sgmlDecl(SgmlDeclEvent *event)
1677 {
1678   grove_->setSd(event->sdPointer(), event->prologSyntaxPointer(), event->instanceSyntaxPointer());
1679   delete event;
1680 }
1681 
setSd(const ConstPtr<Sd> & sd,const ConstPtr<Syntax> & prologSyntax,const ConstPtr<Syntax> & instanceSyntax)1682 void GroveBuilderMessageEventHandler::setSd(const ConstPtr<Sd> &sd, const ConstPtr<Syntax> &prologSyntax, const ConstPtr<Syntax> &instanceSyntax)
1683 {
1684   grove_->setSd(sd, prologSyntax, instanceSyntax);
1685 }
1686 
GroveBuilderEventHandler(unsigned groveIndex,Messenger * mgr,MessageFormatter * msgFmt)1687 GroveBuilderEventHandler::GroveBuilderEventHandler(unsigned groveIndex,
1688 						   Messenger *mgr,
1689 						   MessageFormatter *msgFmt)
1690 : GroveBuilderMessageEventHandler(groveIndex, mgr, msgFmt)
1691 {
1692 }
1693 
appinfo(AppinfoEvent * event)1694 void GroveBuilderEventHandler::appinfo(AppinfoEvent *event)
1695 {
1696   const StringC *appinfo;
1697   if (event->literal(appinfo))
1698     grove_->setAppinfo(*appinfo);
1699   delete event;
1700 }
1701 
endProlog(EndPrologEvent * event)1702 void GroveBuilderEventHandler::endProlog(EndPrologEvent *event)
1703 {
1704   grove_->setDtd(event->dtdPointer());
1705   delete event;
1706 }
1707 
startElement(StartElementEvent * event)1708 void GroveBuilderEventHandler::startElement(StartElementEvent *event)
1709 {
1710   ElementNode::add(*grove_, *event);
1711   delete event;
1712 }
1713 
endElement(EndElementEvent * event)1714 void GroveBuilderEventHandler::endElement(EndElementEvent *event)
1715 {
1716   grove_->pop();
1717   delete event;
1718 }
1719 
data(DataEvent * event)1720 void GroveBuilderEventHandler::data(DataEvent *event)
1721 {
1722   DataNode::add(*grove_, *event);
1723   delete event;
1724 }
1725 
sdataEntity(SdataEntityEvent * event)1726 void GroveBuilderEventHandler::sdataEntity(SdataEntityEvent *event)
1727 {
1728   SdataNode::add(*grove_, *event);
1729   delete event;
1730 }
1731 
nonSgmlChar(NonSgmlCharEvent * event)1732 void GroveBuilderEventHandler::nonSgmlChar(NonSgmlCharEvent *event)
1733 {
1734   NonSgmlNode::add(*grove_, *event);
1735   delete event;
1736 }
1737 
externalDataEntity(ExternalDataEntityEvent * event)1738 void GroveBuilderEventHandler::externalDataEntity(ExternalDataEntityEvent *event)
1739 {
1740   ExternalDataNode::add(*grove_, *event);
1741   delete event;
1742 }
1743 
subdocEntity(SubdocEntityEvent * event)1744 void GroveBuilderEventHandler::subdocEntity(SubdocEntityEvent *event)
1745 {
1746   SubdocNode::add(*grove_, *event);
1747   delete event;
1748 }
1749 
pi(PiEvent * event)1750 void GroveBuilderEventHandler::pi(PiEvent *event)
1751 {
1752   PiNode::add(*grove_, *event);
1753   delete event;
1754 }
1755 
entityDefaulted(EntityDefaultedEvent * event)1756 void GroveBuilderEventHandler::entityDefaulted(EntityDefaultedEvent *event)
1757 {
1758   grove_->addDefaultedEntity(event->entityPointer());
1759   delete event;
1760 }
1761 
make(unsigned index,Messenger * mgr,MessageFormatter * msgFmt,bool validateOnly,NodePtr & root)1762 ErrorCountEventHandler *GroveBuilder::make(unsigned index,
1763 					   Messenger *mgr,
1764 					   MessageFormatter *msgFmt,
1765 					   bool validateOnly,
1766 					   NodePtr &root)
1767 {
1768   GroveBuilderMessageEventHandler *eh;
1769   if (validateOnly)
1770     eh = new GroveBuilderMessageEventHandler(index, mgr, msgFmt);
1771   else
1772     eh = new GroveBuilderEventHandler(index, mgr, msgFmt);
1773   eh->makeInitialRoot(root);
1774   return eh;
1775 }
1776 
make(unsigned index,Messenger * mgr,MessageFormatter * msgFmt,bool validateOnly,const ConstPtr<Sd> & sd,const ConstPtr<Syntax> & prologSyntax,const ConstPtr<Syntax> & instanceSyntax,NodePtr & root)1777 ErrorCountEventHandler *GroveBuilder::make(unsigned index,
1778 					   Messenger *mgr,
1779 					   MessageFormatter *msgFmt,
1780 					   bool validateOnly,
1781 					   const ConstPtr<Sd> &sd,
1782 					   const ConstPtr<Syntax> &prologSyntax,
1783 					   const ConstPtr<Syntax> &instanceSyntax,
1784 					   NodePtr &root)
1785 {
1786   GroveBuilderMessageEventHandler *eh;
1787   if (validateOnly)
1788     eh = new GroveBuilderMessageEventHandler(index, mgr, msgFmt);
1789   else
1790     eh = new GroveBuilderEventHandler(index, mgr, msgFmt);
1791   eh->makeInitialRoot(root);
1792   eh->setSd(sd, prologSyntax, instanceSyntax);
1793   return eh;
1794 }
1795 
setBlocking(bool b)1796 bool GroveBuilder::setBlocking(bool b)
1797 {
1798   bool prev = blockingAccess;
1799   blockingAccess = b;
1800   return prev;
1801 }
1802 
GroveImpl(unsigned groveIndex)1803 GroveImpl::GroveImpl(unsigned groveIndex)
1804 : groveIndex_(groveIndex),
1805   root_(0),
1806   impliedAttributeValue_(new ImpliedAttributeValue),
1807   tailPtr_(0),
1808   freePtr_(0),
1809   nFree_(0),
1810   blocks_(0),
1811   blockTailPtr_(&blocks_),
1812   blockAllocSize_(initialBlockSize),
1813   nBlocksThisSizeAlloced_(0),
1814   complete_(0),
1815   mutexPtr_(&mutex_),
1816   pulseStep_(0),
1817   nEvents_(0),
1818   haveAppinfo_(0),
1819   pendingData_(0),
1820   nElements_(0),
1821   currentLocOrigin_(0),
1822   completeLimitWithLocChunkAfter_(0),
1823   nChunksSinceLocOrigin_(0),
1824   messageList_(0),
1825   messageListTailP_(&messageList_)
1826 {
1827   root_ = new (allocChunk(sizeof(SgmlDocumentChunk))) SgmlDocumentChunk;
1828   root_->origin = 0;
1829   root_->locIndex = 0;
1830   completeLimit_ = freePtr_;
1831   origin_ = root_;
1832   tailPtr_ = &root_->prolog;
1833 }
1834 
~GroveImpl()1835 GroveImpl::~GroveImpl()
1836 {
1837   while (blocks_) {
1838     BlockHeader *tem = blocks_;
1839     blocks_ = blocks_->next;
1840     ::operator delete(tem);
1841   }
1842   while (messageList_) {
1843     MessageItem *tem = messageList_;
1844     messageList_ = *messageList_->nextP();
1845     delete tem;
1846   }
1847 }
1848 
setAppinfo(const StringC & appinfo)1849 void GroveImpl::setAppinfo(const StringC &appinfo)
1850 {
1851   appinfo_ = appinfo;
1852   haveAppinfo_ = 1;
1853 }
1854 
getAppinfo(const StringC * & appinfo) const1855 Boolean GroveImpl::getAppinfo(const StringC *&appinfo) const
1856 {
1857   if (!haveAppinfo_) {
1858     if (!complete_ && sd_.isNull())
1859       return 0; // not available yet
1860     appinfo = 0;
1861   }
1862   else
1863     appinfo = &appinfo_;
1864   return 1;
1865 }
1866 
setSd(const ConstPtr<Sd> & sd,const ConstPtr<Syntax> & prologSyntax,const ConstPtr<Syntax> & instanceSyntax)1867 void GroveImpl::setSd(const ConstPtr<Sd> &sd, const ConstPtr<Syntax> &prologSyntax, const ConstPtr<Syntax> &instanceSyntax)
1868 {
1869   instanceSyntax_ = instanceSyntax;
1870   prologSyntax_ = prologSyntax;
1871   sd_ = sd;
1872 }
1873 
getSd(ConstPtr<Sd> & sd,ConstPtr<Syntax> & prologSyntax,ConstPtr<Syntax> & instanceSyntax) const1874 void GroveImpl::getSd(ConstPtr<Sd> &sd, ConstPtr<Syntax> &prologSyntax, ConstPtr<Syntax> &instanceSyntax) const
1875 {
1876   instanceSyntax = instanceSyntax_;
1877   prologSyntax = prologSyntax_;
1878   sd = sd_;
1879 }
1880 
finishProlog()1881 void GroveImpl::finishProlog()
1882 {
1883   if (root_->prolog)
1884     addBarrier();
1885   tailPtr_ = 0;
1886 }
1887 
finishDocumentElement()1888 void GroveImpl::finishDocumentElement()
1889 {
1890   // Be robust in the case of erroneous documents.
1891   if (root_->epilog == 0) {
1892     addBarrier();
1893     tailPtr_ = &root_->epilog;
1894   }
1895 }
1896 
addBarrier()1897 void GroveImpl::addBarrier()
1898 {
1899   if (freePtr_) {
1900     (void) new (freePtr_) ForwardingChunk(0, 0);
1901     if (nFree_ <= sizeof(ForwardingChunk)) {
1902       nFree_ = 0;
1903       freePtr_ = 0;
1904     }
1905     else {
1906       nFree_ -= sizeof(ForwardingChunk);
1907       freePtr_ += sizeof(ForwardingChunk);
1908     }
1909   }
1910 }
1911 
setComplete()1912 void GroveImpl::setComplete()
1913 {
1914   addBarrier();
1915   mutexPtr_ = 0;
1916   completeLimit_ = 0;
1917   completeLimitWithLocChunkAfter_ = 0;
1918   if (pendingData_ && tailPtr_)
1919     *tailPtr_ = pendingData_;
1920   tailPtr_ = 0;
1921   pendingData_ = 0;
1922   complete_ = 1;
1923   moreNodesCondition_.set();
1924 }
1925 
addDefaultedEntity(const ConstPtr<Entity> & entity)1926 void GroveImpl::addDefaultedEntity(const ConstPtr<Entity> &entity)
1927 {
1928   Mutex::Lock lock(mutexPtr_);
1929   // We need a table of ConstPtr<Entity> but we don't have one.
1930   defaultedEntityTable_.insert((Entity *)entity.pointer());
1931 }
1932 
lookupDefaultedEntity(const StringC & name) const1933 const Entity *GroveImpl::lookupDefaultedEntity(const StringC &name) const
1934 {
1935   Mutex::Lock lock(mutexPtr_);
1936   return defaultedEntityTable_.lookupTemp(name);
1937 }
1938 
defaultedEntityIter() const1939 Dtd::ConstEntityIter GroveImpl::defaultedEntityIter() const
1940 {
1941   ASSERT(complete());
1942   return Dtd::ConstEntityIter(defaultedEntityTable_);
1943 }
1944 
maybeMoreSiblings1(const ParentChunk * chunk) const1945 Boolean GroveImpl::maybeMoreSiblings1(const ParentChunk *chunk) const
1946 {
1947   for (const ParentChunk *open = origin_; open; open = open->origin)
1948     if (open == chunk)
1949       return 1;
1950   // for multi-thread case
1951   return tailPtr_ == &chunk->nextSibling || chunk->nextSibling != 0;
1952 }
1953 
allocFinish(size_t n)1954 void *GroveImpl::allocFinish(size_t n)
1955 {
1956   if (++nBlocksThisSizeAlloced_ >= maxBlocksPerSize) {
1957      blockAllocSize_ *= 2;
1958      nBlocksThisSizeAlloced_ = 0;
1959   }
1960   size_t allocSize = n + (sizeof(ForwardingChunk) + sizeof(BlockHeader));
1961   if (allocSize < blockAllocSize_) {
1962     nFree_ = blockAllocSize_ - allocSize;
1963     allocSize = blockAllocSize_;
1964   }
1965   else
1966     nFree_ = 0;
1967   *blockTailPtr_ = new (::operator new(allocSize)) BlockHeader;
1968   char *chunkStart = (char *)(*blockTailPtr_ + 1);
1969   blockTailPtr_ = &(*blockTailPtr_)->next;
1970   if (freePtr_)
1971     (void)new (freePtr_) ForwardingChunk((const Chunk *)chunkStart, origin_);
1972   freePtr_ = chunkStart + n;
1973   return chunkStart;
1974 }
1975 
getLocation(Location & loc) const1976 AccessResult ChunkNode::getLocation(Location &loc) const
1977 {
1978   const Origin *origin = grove()->currentLocOrigin();
1979   for (const Chunk *p = chunk_->after(); p; p = p->after()) {
1980     if (p == grove()->completeLimitWithLocChunkAfter()) {
1981       while (!p->getLocOrigin(origin)) {
1982 	p = p->after();
1983 	ASSERT(p != 0);
1984       }
1985       break;
1986     }
1987     if (p == grove()->completeLimit() || p->getLocOrigin(origin))
1988       break;
1989   }
1990   if (!origin)
1991     return accessNull;
1992   loc = Location(new GroveImplProxyOrigin(grove(), origin), chunk_->locIndex);
1993   return accessOK;
1994 }
1995 
storeLocOrigin(const ConstPtr<Origin> & locOrigin)1996 void GroveImpl::storeLocOrigin(const ConstPtr<Origin> &locOrigin)
1997 {
1998   LocOriginChunk *chunk
1999     = new (allocChunk(sizeof(LocOriginChunk)))
2000 	  LocOriginChunk(currentLocOrigin_);
2001   chunk->origin = origin_;
2002   completeLimitWithLocChunkAfter_ = completeLimit_;
2003   nChunksSinceLocOrigin_ = 0;
2004   if (locOrigin.pointer() == currentLocOrigin_)
2005     return;
2006   if (currentLocOrigin_
2007       && locOrigin == currentLocOrigin_->parent().origin()) {
2008     // Don't need to store it.
2009     currentLocOrigin_ = locOrigin.pointer();
2010     return;
2011   }
2012   currentLocOrigin_ = locOrigin.pointer();
2013   if (locOrigin.isNull())
2014     return;
2015   origins_.push_back(locOrigin);
2016 }
2017 
proxifyLocation(const Location & loc,Location & ret) const2018 AccessResult GroveImpl::proxifyLocation(const Location &loc, Location &ret) const
2019 {
2020   if (loc.origin().isNull())
2021     return accessNull;
2022   ret = Location(new GroveImplProxyOrigin(this, loc.origin().pointer()),
2023 		 loc.index());
2024   return accessOK;
2025 }
2026 
nodeList() const2027 NodeListPtr AttributesNamedNodeList::nodeList() const
2028 {
2029   const AttributeDefinitionList *defList = attDefList();
2030   if (!defList || defList->size() == 0)
2031     return new BaseNodeList;
2032   else
2033     return new SiblingNodeList(makeAttributeAsgnNode(grove(), 0));
2034 }
2035 
2036 AccessResult
namedNodeU(const StringC & str,NodePtr & ptr) const2037 AttributesNamedNodeList::namedNodeU(const StringC &str, NodePtr &ptr) const
2038 {
2039   const AttributeDefinitionList *defList = attDefList();
2040   if (defList) {
2041     for (size_t i = 0; i < defList->size(); i++)
2042       if (defList->def(i)->name() == str) {
2043         ptr.assign(makeAttributeAsgnNode(grove(), i));
2044 	return accessOK;
2045       }
2046   }
2047   return accessNull;
2048 }
2049 
accept(NodeVisitor & visitor)2050 void SgmlDocumentNode::accept(NodeVisitor &visitor)
2051 {
2052   visitor.sgmlDocument(*this);
2053 }
2054 
getSgmlConstants(NodePtr & ptr) const2055 AccessResult SgmlDocumentNode::getSgmlConstants(NodePtr &ptr) const
2056 {
2057   ptr.assign(new SgmlConstantsNode(grove()));
2058   return accessOK;
2059 }
2060 
getApplicationInfo(GroveString & str) const2061 AccessResult SgmlDocumentNode::getApplicationInfo(GroveString &str) const
2062 {
2063   const StringC *appinfo;
2064   while (!grove()->getAppinfo(appinfo))
2065     if (!grove()->waitForMoreNodes())
2066       return accessTimeout;
2067   if (!appinfo)
2068     return accessNull;
2069   setString(str, *appinfo);
2070   return accessOK;
2071 }
2072 
getDocumentElement(NodePtr & ptr) const2073 AccessResult SgmlDocumentNode::getDocumentElement(NodePtr &ptr) const
2074 {
2075   while (chunk()->documentElement == 0) {
2076     if (grove()->complete()) {
2077       // Just in case another thread crept
2078       if (chunk()->documentElement)
2079 	break;
2080       return accessNull;
2081     }
2082     if (!grove()->waitForMoreNodes())
2083       return accessTimeout;
2084   }
2085   return chunk()->documentElement->setNodePtrFirst(ptr, this);
2086 }
2087 
getProlog(NodeListPtr & ptr) const2088 AccessResult SgmlDocumentNode::getProlog(NodeListPtr &ptr) const
2089 {
2090   while (chunk()->prolog == 0) {
2091     if (chunk()->documentElement || grove()->complete())
2092       break;
2093     if (!grove()->waitForMoreNodes())
2094       return accessTimeout;
2095   }
2096   if (chunk()->prolog == 0)
2097     ptr.assign(new BaseNodeList);
2098   else {
2099     NodePtr tem;
2100     chunk()->prolog->setNodePtrFirst(tem, this);
2101     ptr.assign(new SiblingNodeList(tem));
2102   }
2103   return accessOK;
2104 }
2105 
getEpilog(NodeListPtr & ptr) const2106 AccessResult SgmlDocumentNode::getEpilog(NodeListPtr &ptr) const
2107 {
2108   while (chunk()->epilog == 0) {
2109     if (grove()->complete())
2110       break;
2111     if (!grove()->waitForMoreNodes())
2112       return accessTimeout;
2113   }
2114   if (chunk()->epilog == 0)
2115     ptr.assign(new BaseNodeList);
2116   else {
2117     NodePtr tem;
2118     chunk()->epilog->setNodePtrFirst(tem, this);
2119     ptr.assign(new SiblingNodeList(tem));
2120   }
2121   return accessOK;
2122 }
2123 
getElements(NamedNodeListPtr & ptr) const2124 AccessResult SgmlDocumentNode::getElements(NamedNodeListPtr &ptr) const
2125 {
2126   while (!grove()->root()->documentElement) {
2127     if (grove()->complete()) {
2128       if (grove()->root()->documentElement)
2129 	break;
2130       return accessNull;
2131     }
2132     if (!grove()->waitForMoreNodes())
2133       return accessTimeout;
2134   }
2135   if (!grove()->generalSubstTable())
2136     return accessNull;
2137   ptr.assign(new ElementsNamedNodeList(grove()));
2138   return accessOK;
2139 }
2140 
getEntities(NamedNodeListPtr & ptr) const2141 AccessResult SgmlDocumentNode::getEntities(NamedNodeListPtr &ptr) const
2142 {
2143   while (!grove()->governingDtd()) {
2144     if (grove()->complete()) {
2145       if (grove()->governingDtd())
2146 	break;
2147       return accessNull;
2148     }
2149     if (!grove()->waitForMoreNodes())
2150       return accessTimeout;
2151   }
2152   ptr.assign(new DocEntitiesNamedNodeList(grove()));
2153   return accessOK;
2154 }
2155 
getDefaultedEntities(NamedNodeListPtr & ptr) const2156 AccessResult SgmlDocumentNode::getDefaultedEntities(NamedNodeListPtr &ptr) const
2157 {
2158   while (!grove()->complete())
2159     if (!grove()->waitForMoreNodes())
2160       return accessTimeout;
2161   ptr.assign(new DefaultedEntitiesNamedNodeList(grove()));
2162   return accessOK;
2163 }
2164 
getGoverningDoctype(NodePtr & ptr) const2165 AccessResult SgmlDocumentNode::getGoverningDoctype(NodePtr &ptr) const
2166 {
2167   while (!grove()->governingDtd()) {
2168     if (grove()->complete()) {
2169       if (grove()->governingDtd())
2170 	break;
2171       return accessNull;
2172     }
2173     if (!grove()->waitForMoreNodes())
2174       return accessTimeout;
2175   }
2176   ptr.assign(new DocumentTypeNode(grove(), grove()->governingDtd()));
2177   return accessOK;
2178 }
2179 
getDoctypesAndLinktypes(NamedNodeListPtr & ptr) const2180 AccessResult SgmlDocumentNode::getDoctypesAndLinktypes(NamedNodeListPtr &ptr) const
2181 {
2182   while (!grove()->governingDtd()) {
2183     if (grove()->complete()) {
2184       if (grove()->governingDtd())
2185 	break;
2186       return accessNull;
2187     }
2188     if (!grove()->waitForMoreNodes())
2189       return accessTimeout;
2190   }
2191   ptr.assign(new DoctypesAndLinktypesNamedNodeList(grove()));
2192   return accessOK;
2193 }
2194 
getMessages(NodeListPtr & ptr) const2195 AccessResult SgmlDocumentNode::getMessages(NodeListPtr &ptr) const
2196 {
2197   while (grove()->messageList() == 0) {
2198     if (grove()->complete())
2199       break;
2200     if (!grove()->waitForMoreNodes())
2201       return accessTimeout;
2202   }
2203   if (grove()->messageList()) {
2204     NodePtr tem(new MessageNode(grove(), grove()->messageList()));
2205     ptr.assign(new SiblingNodeList(tem));
2206   }
2207   else
2208     ptr.assign(new BaseNodeList);
2209   return accessOK;
2210 }
2211 
getSd(ConstPtr<Sd> & sd,ConstPtr<Syntax> & prologSyntax,ConstPtr<Syntax> & instanceSyntax) const2212 AccessResult SgmlDocumentNode::getSd(ConstPtr<Sd> &sd,
2213 				     ConstPtr<Syntax> &prologSyntax,
2214 				     ConstPtr<Syntax> &instanceSyntax) const
2215 {
2216   while (!grove()->complete()) {
2217     if (!grove()->waitForMoreNodes())
2218       return accessTimeout;
2219   }
2220   grove()->getSd(sd, prologSyntax, instanceSyntax);
2221   if (!sd.isNull() && !prologSyntax.isNull() && !instanceSyntax.isNull())
2222     return accessOK;
2223   return accessNull;
2224 }
2225 
2226 AccessResult
setNodePtrFirst(NodePtr & ptr,const BaseNode * node) const2227 SgmlDocumentChunk::setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const
2228 {
2229   ptr.assign(new SgmlDocumentNode(node->grove(), this));
2230   return accessOK;
2231 }
2232 
DocumentTypeNode(const GroveImpl * grove,const Dtd * dtd)2233 DocumentTypeNode::DocumentTypeNode(const GroveImpl *grove, const Dtd *dtd)
2234 : BaseNode(grove), dtd_(dtd)
2235 {
2236 }
2237 
nextChunkSibling(NodePtr &) const2238 AccessResult DocumentTypeNode::nextChunkSibling(NodePtr &) const
2239 {
2240   return accessNull;
2241 }
2242 
getName(GroveString & str) const2243 AccessResult DocumentTypeNode::getName(GroveString &str) const
2244 {
2245   setString(str, dtd_->name());
2246   return accessOK;
2247 }
2248 
getGoverning(bool & governing) const2249 AccessResult DocumentTypeNode::getGoverning(bool &governing) const
2250 {
2251   governing = dtd_->isBase();
2252   return accessOK;
2253 }
2254 
getGeneralEntities(NamedNodeListPtr & ptr) const2255 AccessResult DocumentTypeNode::getGeneralEntities(NamedNodeListPtr &ptr) const
2256 {
2257   ptr.assign(new GeneralEntitiesNamedNodeList(grove(), dtd_));
2258   return accessOK;
2259 }
2260 
getNotations(NamedNodeListPtr & ptr) const2261 AccessResult DocumentTypeNode::getNotations(NamedNodeListPtr &ptr) const
2262 {
2263   ptr.assign(new NotationsNamedNodeList(grove(), dtd_));
2264   return accessOK;
2265 }
2266 
getOrigin(NodePtr & ptr) const2267 AccessResult DocumentTypeNode::getOrigin(NodePtr &ptr) const
2268 {
2269   ptr.assign(new SgmlDocumentNode(grove(), grove()->root()));
2270   return accessOK;
2271 }
2272 
accept(NodeVisitor & visitor)2273 void DocumentTypeNode::accept(NodeVisitor &visitor)
2274 {
2275   visitor.documentType(*this);
2276 }
2277 
same(const BaseNode & node) const2278 bool DocumentTypeNode::same(const BaseNode &node) const
2279 {
2280   return node.same2(this);
2281 }
2282 
same2(const DocumentTypeNode * node) const2283 bool DocumentTypeNode::same2(const DocumentTypeNode *node) const
2284 {
2285   return dtd_ == node->dtd_;
2286 }
2287 
SgmlConstantsNode(const GroveImpl * grove)2288 SgmlConstantsNode::SgmlConstantsNode(const GroveImpl *grove)
2289 : BaseNode(grove)
2290 {
2291 }
2292 
getOrigin(NodePtr & ptr) const2293 AccessResult SgmlConstantsNode::getOrigin(NodePtr &ptr) const
2294 {
2295   ptr.assign(new SgmlDocumentNode(grove(), grove()->root()));
2296   return accessOK;
2297 }
2298 
accept(NodeVisitor & visitor)2299 void SgmlConstantsNode::accept(NodeVisitor &visitor)
2300 {
2301   visitor.sgmlConstants(*this);
2302 }
2303 
same(const BaseNode & node) const2304 bool SgmlConstantsNode::same(const BaseNode &node) const
2305 {
2306   return node.same2(this);
2307 }
2308 
same2(const SgmlConstantsNode *) const2309 bool SgmlConstantsNode::same2(const SgmlConstantsNode *) const
2310 {
2311   return 1;
2312 }
2313 
MessageNode(const GroveImpl * grove,const MessageItem * item)2314 MessageNode::MessageNode(const GroveImpl *grove, const MessageItem *item)
2315 : BaseNode(grove), item_(item)
2316 {
2317 }
2318 
getOrigin(NodePtr & ptr) const2319 AccessResult MessageNode::getOrigin(NodePtr &ptr) const
2320 {
2321   ptr.assign(new SgmlDocumentNode(grove(), grove()->root()));
2322   return accessOK;
2323 }
2324 
nextChunkSibling(NodePtr & ptr) const2325 AccessResult MessageNode::nextChunkSibling(NodePtr &ptr) const
2326 {
2327   while (!item_->next()) {
2328     if (grove()->complete()) {
2329       if (item_->next())
2330 	break;
2331       return accessNull;
2332     }
2333     if (!grove()->waitForMoreNodes())
2334       return accessTimeout;
2335   }
2336   const MessageItem *p = item_->next();
2337   if (!p)
2338     return accessNull;
2339   ptr.assign(new MessageNode(grove(), p));
2340   return accessOK;
2341 }
2342 
firstSibling(NodePtr & ptr) const2343 AccessResult MessageNode::firstSibling(NodePtr &ptr) const
2344 {
2345   ptr.assign(new MessageNode(grove(), grove()->messageList()));
2346   return accessOK;
2347 }
2348 
siblingsIndex(unsigned long & n) const2349 AccessResult MessageNode::siblingsIndex(unsigned long &n) const
2350 {
2351   n = 0;
2352   for (const MessageItem *p = grove()->messageList(); p != item_; p = p->next())
2353     n++;
2354   return accessOK;
2355 }
2356 
accept(NodeVisitor & visitor)2357 void MessageNode::accept(NodeVisitor &visitor)
2358 {
2359   visitor.message(*this);
2360 }
2361 
same(const BaseNode & node) const2362 bool MessageNode::same(const BaseNode &node) const
2363 {
2364   return node.same2(this);
2365 }
2366 
same2(const MessageNode * node) const2367 bool MessageNode::same2(const MessageNode *node) const
2368 {
2369   return item_ == node->item_;
2370 }
2371 
getLocation(Location & loc) const2372 AccessResult MessageNode::getLocation(Location &loc) const
2373 {
2374   return grove()->proxifyLocation(item_->loc(), loc);
2375 }
2376 
getText(GroveString & str) const2377 AccessResult MessageNode::getText(GroveString &str) const
2378 {
2379   setString(str, item_->text());
2380   return accessOK;
2381 }
2382 
getSeverity(Severity & severity) const2383 AccessResult MessageNode::getSeverity(Severity &severity) const
2384 {
2385   severity = item_->severity();
2386   return accessOK;
2387 }
2388 
nextChunkSibling(NodePtr & ptr) const2389 AccessResult ElementNode::nextChunkSibling(NodePtr &ptr) const
2390 {
2391   while (!chunk()->nextSibling) {
2392     if (!grove()->maybeMoreSiblings(chunk())) {
2393       // Allow for the possibility of invalid documents with elements in the epilog.
2394       if ((const Chunk *)chunk() == grove()->root()->documentElement)
2395 	return accessNotInClass;
2396       else
2397         return accessNull;
2398     }
2399     if (!grove()->waitForMoreNodes())
2400       return accessTimeout;
2401   }
2402   return chunk()->nextSibling->setNodePtrFirst(ptr, this);
2403 }
2404 
2405 // This is a duplicate of ChunkNode::nextChunkAfter
2406 // to take advantage of overloaded setNodePtrFirst.
2407 
nextChunkAfter(NodePtr & nd) const2408 AccessResult ElementNode::nextChunkAfter(NodePtr &nd) const
2409 {
2410   const Chunk *p = chunk_->after();
2411   while (p == grove()->completeLimit())
2412     if (!grove()->waitForMoreNodes())
2413       return accessTimeout;
2414   return p->setNodePtrFirst(nd, this);
2415 }
2416 
getFollowing(const GroveImpl * grove,const Chunk * & f,unsigned long & n) const2417 AccessResult ElementChunk::getFollowing(const GroveImpl *grove,
2418 					const Chunk *&f,
2419 					unsigned long &n) const
2420 {
2421   while (!nextSibling) {
2422     if (!grove->maybeMoreSiblings(this)) {
2423       if ((const Chunk *)origin == grove->root())
2424 	return accessNotInClass;
2425       else
2426         return accessNull;
2427     }
2428     if (!grove->waitForMoreNodes())
2429       return accessTimeout;
2430   }
2431   f = nextSibling;
2432   n = 1;
2433   return accessOK;
2434 }
2435 
firstChild(NodePtr & ptr) const2436 AccessResult ElementNode::firstChild(NodePtr &ptr) const
2437 {
2438   const Chunk *p = chunk()->after();
2439   while (p == grove()->completeLimit()) {
2440     if (!grove()->waitForMoreNodes())
2441       return accessTimeout;
2442   }
2443   if ((const Chunk *)(p->origin) == chunk())
2444     return p->setNodePtrFirst(ptr, this);
2445   return accessNull;
2446 }
2447 
attributeRef(unsigned long n,NodePtr & ptr) const2448 AccessResult ElementNode::attributeRef(unsigned long n, NodePtr &ptr) const
2449 {
2450   const AttributeDefinitionList *defList = chunk()->attDefList();
2451   if (!defList || n >= defList->size())
2452     return accessNull;
2453   ptr.assign(new ElementAttributeAsgnNode(grove(), size_t(n), chunk()));
2454   return accessOK;
2455 }
2456 
getAttributes(NamedNodeListPtr & ptr) const2457 AccessResult ElementNode::getAttributes(NamedNodeListPtr &ptr) const
2458 {
2459   ptr.assign(new ElementAttributesNamedNodeList(grove(), chunk()));
2460   return accessOK;
2461 }
2462 
getGi(GroveString & str) const2463 AccessResult ElementNode::getGi(GroveString &str) const
2464 {
2465   setString(str, chunk()->type->name());
2466   return accessOK;
2467 }
2468 
hasGi(GroveString str) const2469 bool ElementNode::hasGi(GroveString str) const
2470 {
2471   const StringC &gi = chunk()->type->name();
2472   size_t len = gi.size();
2473   if (len != str.size())
2474     return 0;
2475   const SubstTable<Char> *subst = grove()->generalSubstTable();
2476   if (!subst)
2477     return 0;
2478   for (size_t i = 0; i < len; i++)
2479     if ((*subst)[str[i]] != gi[i])
2480       return 0;
2481   return 1;
2482 }
2483 
getId(GroveString & str) const2484 AccessResult ElementNode::getId(GroveString &str) const
2485 {
2486   const StringC *id = chunk()->id();
2487   if (!id)
2488     return accessNull;
2489   setString(str, *id);
2490   return accessOK;
2491 }
2492 
elementIndex(unsigned long & i) const2493 AccessResult ElementNode::elementIndex(unsigned long &i) const
2494 {
2495   i = chunk()->elementIndex;
2496   return accessOK;
2497 }
2498 
getContent(NodeListPtr & ptr) const2499 AccessResult ElementNode::getContent(NodeListPtr &ptr) const
2500 {
2501   return children(ptr);
2502 }
2503 
getMustOmitEndTag(bool & b) const2504 AccessResult ElementNode::getMustOmitEndTag(bool &b) const
2505 {
2506   b = chunk()->mustOmitEndTag();
2507   return accessOK;
2508 }
2509 
getIncluded(bool & b) const2510 AccessResult ElementNode::getIncluded(bool &b) const
2511 {
2512   b = chunk()->included();
2513   return accessOK;
2514 }
2515 
accept(NodeVisitor & visitor)2516 void ElementNode::accept(NodeVisitor &visitor)
2517 {
2518   visitor.element(*this);
2519 }
2520 
2521 ElementChunk *
makeAttElementChunk(GroveImpl & grove,const StartElementEvent & event,Boolean & hasId)2522 ElementNode::makeAttElementChunk(GroveImpl &grove,
2523 				 const StartElementEvent &event,
2524 				 Boolean &hasId)
2525 {
2526   const AttributeList &atts = event.attributes();
2527   size_t nAtts = atts.size();
2528   while (nAtts > 0 && !atts.specified(nAtts - 1) && !atts.current(nAtts - 1))
2529     nAtts--;
2530   ElementChunk *chunk;
2531   void *mem
2532     = grove.allocChunk(sizeof(AttElementChunk) + nAtts * sizeof(AttributeValue *));
2533   if (event.included()) {
2534     // Workaround VC++ 4.1 bug.
2535     AttElementChunk *tem = new (mem) IncludedAttElementChunk(nAtts);
2536     chunk = tem;
2537   }
2538   else
2539     chunk = new (mem) AttElementChunk(nAtts);
2540   const AttributeValue **values
2541     = (const AttributeValue **)(((AttElementChunk *)chunk) + 1);
2542   const AttributeDefinitionList *defList
2543     = event.elementType()->attributeDef().pointer();
2544   unsigned idIndex;
2545   if (atts.idIndex(idIndex) && atts.specified(idIndex) && atts.value(idIndex))
2546     hasId = 1;
2547   else
2548     hasId = 0;
2549   for (size_t i = 0; i < nAtts; i++) {
2550     if (atts.specified(i) || atts.current(i)) {
2551       grove.storeAttributeValue(atts.valuePointer(i));
2552       values[i] = atts.value(i);
2553     }
2554     else {
2555       // If we stored a reference to the implied attribute value in the
2556       // Dtd then it would be safe just to use atts.value(i) here.
2557       // But that would mean we couldn't conveniently tell whether it
2558       // was specified or implied.
2559       values[i] = defList->def(i)->defaultValue(grove.impliedAttributeValue());
2560     }
2561   }
2562   return chunk;
2563 }
2564 
after() const2565 const Chunk *AttElementChunk::after() const
2566 {
2567   return (const Chunk *)((char *)(this + 1)
2568 			 + (sizeof(const AttributeValue *) * nAtts));
2569 }
2570 
2571 const AttributeValue *
attributeValue(size_t attIndex,const GroveImpl & grove) const2572 AttElementChunk::attributeValue(size_t attIndex, const GroveImpl &grove)
2573      const
2574 {
2575   if (attIndex < nAtts)
2576     return ((const AttributeValue **)(this + 1))[attIndex];
2577   else
2578     return ElementChunk::attributeValue(attIndex, grove);
2579 }
2580 
id() const2581 const StringC *AttElementChunk::id() const
2582 {
2583   size_t i = ElementChunk::attDefList()->idIndex();
2584   if (i == size_t(-1) || i >= nAtts)
2585     return 0;
2586   const AttributeValue *av = ((const AttributeValue **)(this + 1))[i];
2587   if (!av)
2588     return 0;
2589   const Text *t = av->text();
2590   if (!t)
2591     return 0;
2592   return &t->string();
2593 }
2594 
mustOmitEndTag() const2595 Boolean AttElementChunk::mustOmitEndTag() const
2596 {
2597   if (ElementChunk::mustOmitEndTag())
2598     return 1;
2599   const AttributeDefinitionList *adl = ElementChunk::attDefList();
2600   size_t nAtts = adl->size();
2601   const AttributeValue **atts = (const AttributeValue **)(this + 1);
2602   for (size_t i = 0; i < nAtts; i++)
2603     if (adl->def(i)->isConref() && atts[i] && atts[i]->text())
2604       return 1;
2605   return 0;
2606 }
2607 
after() const2608 const Chunk *ElementChunk::after() const
2609 {
2610   return this + 1;
2611 }
2612 
2613 const AttributeValue *
attributeValue(size_t attIndex,const GroveImpl & grove) const2614 ElementChunk::attributeValue(size_t attIndex, const GroveImpl &grove) const
2615 {
2616   return attDefList()->def(attIndex)->defaultValue(grove.impliedAttributeValue());
2617 }
2618 
mustOmitEndTag() const2619 Boolean ElementChunk::mustOmitEndTag() const
2620 {
2621   return type->definition()->declaredContent() == ElementDefinition::empty;
2622 }
2623 
included() const2624 Boolean IncludedElementChunk::included() const
2625 {
2626   return 1;
2627 }
2628 
included() const2629 Boolean IncludedAttElementChunk::included() const
2630 {
2631   return 1;
2632 }
2633 
included() const2634 Boolean ElementChunk::included() const
2635 {
2636   return 0;
2637 }
2638 
2639 AccessResult
setNodePtrFirst(NodePtr & ptr,const BaseNode * node) const2640 ElementChunk::setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const
2641 {
2642   ptr.assign(new ElementNode(node->grove(), this));
2643   return accessOK;
2644 }
2645 
2646 AccessResult
setNodePtrFirst(NodePtr & ptr,const ElementNode * node) const2647 ElementChunk::setNodePtrFirst(NodePtr &ptr, const ElementNode *node) const
2648 {
2649   if (node->canReuse(ptr))
2650     ((ElementNode *)node)->reuseFor(this);
2651   else
2652     ptr.assign(new ElementNode(node->grove(), this));
2653   return accessOK;
2654 }
2655 
2656 AccessResult
setNodePtrFirst(NodePtr & ptr,const DataNode * node) const2657 ElementChunk::setNodePtrFirst(NodePtr &ptr, const DataNode *node) const
2658 {
2659   ptr.assign(new ElementNode(node->grove(), this));
2660   return accessOK;
2661 }
2662 
ElementAttributeOrigin(const ElementChunk * chunk)2663 ElementAttributeOrigin::ElementAttributeOrigin(const ElementChunk *chunk)
2664 : chunk_(chunk)
2665 {
2666 }
2667 
attDefList() const2668 const AttributeDefinitionList *ElementAttributeOrigin::attDefList() const
2669 {
2670   return chunk_->attDefList();
2671 }
2672 
2673 
2674 const AttributeValue *
attributeValue(size_t attIndex,const GroveImpl & grove) const2675 ElementAttributeOrigin::attributeValue(size_t attIndex, const GroveImpl &grove) const
2676 {
2677   return chunk_->attributeValue(attIndex, grove);
2678 }
2679 
2680 
2681 AccessResult
setNodePtrAttributeOrigin(NodePtr & ptr,const BaseNode * node) const2682 ElementAttributeOrigin::setNodePtrAttributeOrigin(NodePtr &ptr,
2683 						  const BaseNode *node) const
2684 {
2685   return chunk_->setNodePtrFirst(ptr, node);
2686 }
2687 
2688 
2689 Node *ElementAttributeOrigin
makeCdataAttributeValueNode(const GroveImpl * grove,const AttributeValue * value,size_t attIndex,const TextIter & iter,size_t charIndex) const2690 ::makeCdataAttributeValueNode(const GroveImpl *grove,
2691 			      const AttributeValue *value,
2692 			      size_t attIndex,
2693 			      const TextIter &iter,
2694 			      size_t charIndex) const
2695 {
2696   return new ElementCdataAttributeValueNode(grove, value, attIndex, iter,
2697 					    charIndex, chunk_);
2698 }
2699 
2700 
2701 Node *ElementAttributeOrigin
makeAttributeValueTokenNode(const GroveImpl * grove,const TokenizedAttributeValue * value,size_t attIndex,size_t tokenIndex) const2702 ::makeAttributeValueTokenNode(const GroveImpl *grove,
2703 			      const TokenizedAttributeValue *value,
2704 			      size_t attIndex,
2705 			      size_t tokenIndex) const
2706 {
2707   return new ElementAttributeValueTokenNode(grove, value, attIndex,
2708 					    tokenIndex, chunk_);
2709 }
2710 
2711 Node *ElementAttributeOrigin
makeAttributeAsgnNode(const GroveImpl * grove,size_t attIndex) const2712 ::makeAttributeAsgnNode(const GroveImpl *grove,
2713 			size_t attIndex) const
2714 {
2715   return new ElementAttributeAsgnNode(grove, attIndex, chunk_);
2716 }
2717 
attributeOriginId() const2718 const void *ElementAttributeOrigin::attributeOriginId() const
2719 {
2720   return chunk_;
2721 }
2722 
same(const BaseNode & node) const2723 bool DataNode::same(const BaseNode &node) const
2724 {
2725   return node.same2(this);
2726 }
2727 
same2(const DataNode * node) const2728 bool DataNode::same2(const DataNode *node) const
2729 {
2730   return chunk_ == node->chunk_ && index_ == node->index_;
2731 }
2732 
chunkContains(const Node & node) const2733 bool DataNode::chunkContains(const Node &node) const
2734 {
2735   if (!sameGrove(node))
2736     return 0;
2737   return ((const BaseNode &)node).inChunk(this);
2738 }
2739 
inChunk(const DataNode * node) const2740 bool DataNode::inChunk(const DataNode *node) const
2741 {
2742   return chunk_ == node->chunk_ && index_ >= node->index_;
2743 }
2744 
charChunk(const SdataMapper &,GroveString & str) const2745 AccessResult DataNode::charChunk(const SdataMapper &, GroveString &str) const
2746 {
2747   str.assign(chunk()->data() + index_, chunk()->size - index_);
2748   return accessOK;
2749 }
2750 
accept(NodeVisitor & visitor)2751 void DataNode::accept(NodeVisitor &visitor)
2752 {
2753   visitor.dataChar(*this);
2754 }
2755 
hash() const2756 unsigned long DataNode::hash() const
2757 {
2758   return secondHash(ChunkNode::hash() + index_);
2759 }
2760 
getNonSgml(unsigned long &) const2761 AccessResult DataNode::getNonSgml(unsigned long &) const
2762 {
2763   return accessNull;
2764 }
2765 
nextSibling(NodePtr & ptr) const2766 AccessResult DataNode::nextSibling(NodePtr &ptr) const
2767 {
2768   if (index_ + 1 < chunk()->size) {
2769     if (canReuse(ptr))
2770       ((DataNode *)this)->index_ += 1;
2771     else
2772       ptr.assign(new DataNode(grove(), chunk(), index_ + 1));
2773     return accessOK;
2774   }
2775   return DataNode::nextChunkSibling(ptr);
2776 }
2777 
nextChunkAfter(NodePtr & nd) const2778 AccessResult DataNode::nextChunkAfter(NodePtr &nd) const
2779 {
2780   const Chunk *p = chunk_->after();
2781   while (p == grove()->completeLimit())
2782     if (!grove()->waitForMoreNodes())
2783       return accessTimeout;
2784   return p->setNodePtrFirst(nd, this);
2785 }
2786 
followSiblingRef(unsigned long i,NodePtr & ptr) const2787 AccessResult DataNode::followSiblingRef(unsigned long i, NodePtr &ptr) const
2788 {
2789   if (i < chunk()->size - index_ - 1) {
2790     if (canReuse(ptr))
2791       ((DataNode *)this)->index_ += 1 + size_t(i);
2792     else
2793       ptr.assign(new DataNode(grove(), chunk(), index_ + size_t(i) + 1));
2794     return accessOK;
2795   }
2796   return ChunkNode::followSiblingRef(i - (chunk()->size - index_ - 1), ptr);
2797 }
2798 
siblingsIndex(unsigned long & i) const2799 AccessResult DataNode::siblingsIndex(unsigned long &i) const
2800 {
2801   AccessResult ret = ChunkNode::siblingsIndex(i);
2802   if (ret == accessOK)
2803     i += index_;
2804   return ret;
2805 }
2806 
getLocation(Location & loc) const2807 AccessResult DataNode::getLocation(Location &loc) const
2808 {
2809   AccessResult ret = ChunkNode::getLocation(loc);
2810   if (ret == accessOK)
2811     loc += index_;
2812   return ret;
2813 }
2814 
getFollowing(const GroveImpl * grove,const Chunk * & f,unsigned long & i) const2815 AccessResult DataChunk::getFollowing(const GroveImpl *grove,
2816 				     const Chunk *&f,
2817 				     unsigned long &i) const
2818 {
2819   // We could call Chunk::getFollowing to do most of
2820   // the work, but that would cost us a couple of extra
2821   // virtual function calls.
2822   const Chunk *p = CharsChunk::after();
2823   while (p == grove->completeLimit())
2824     if (!grove->waitForMoreNodes())
2825       return accessTimeout;
2826   if (p->origin != origin)
2827     return accessNull;
2828   i = size;
2829   f = p;
2830   return accessOK;
2831 }
2832 
setNodePtrFirst(NodePtr & ptr,const BaseNode * node) const2833 AccessResult DataChunk::setNodePtrFirst(NodePtr &ptr,
2834 					const BaseNode *node) const
2835 {
2836   ptr.assign(new DataNode(node->grove(), this, 0));
2837   return accessOK;
2838 }
2839 
2840 // This just saves us a virtual function call in a common case
setNodePtrFirst(NodePtr & ptr,const ElementNode * node) const2841 AccessResult DataChunk::setNodePtrFirst(NodePtr &ptr,
2842 					const ElementNode *node) const
2843 {
2844   ptr.assign(new DataNode(node->grove(), this, 0));
2845   return accessOK;
2846 }
2847 
setNodePtrFirst(NodePtr & ptr,const DataNode * node) const2848 AccessResult DataChunk::setNodePtrFirst(NodePtr &ptr, const DataNode *node)
2849      const
2850 {
2851   if (node->canReuse(ptr))
2852     ((DataNode *)node)->reuseFor(this, 0);
2853   else
2854     ptr.assign(new DataNode(node->grove(), this, 0));
2855   return accessOK;
2856 }
2857 
getSystemData(GroveString & str) const2858 AccessResult PiNode::getSystemData(GroveString &str) const
2859 {
2860   str.assign(chunk()->data(), chunk()->size);
2861   return accessOK;
2862 }
2863 
add(GroveImpl & grove,const PiEvent & event)2864 void PiNode::add(GroveImpl &grove, const PiEvent &event)
2865 {
2866   const Entity *entity = event.entity();
2867   if (entity)
2868     PiEntityNode::add(grove, entity, event.location());
2869   else {
2870     grove.setLocOrigin(event.location().origin());
2871     size_t dataLen = event.dataLength();
2872     void *mem = grove.allocChunk(CharsChunk::allocSize(dataLen));
2873     PiChunk *chunk;
2874     if (grove.haveRootOrigin()) {
2875       if (grove.root()->documentElement)
2876 	chunk = new (mem) EpilogPiChunk;
2877       else
2878 	chunk = new (mem) PrologPiChunk;
2879     }
2880     else
2881       chunk = new (mem) PiChunk;
2882     chunk->size = dataLen;
2883     chunk->locIndex = event.location().index();
2884     memcpy(chunk + 1, event.data(), dataLen * sizeof(Char));
2885     grove.appendSibling(chunk);
2886   }
2887 }
2888 
setNodePtrFirst(NodePtr & ptr,const BaseNode * node) const2889 AccessResult PiChunk::setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const
2890 {
2891   ptr.assign(new PiNode(node->grove(), this));
2892   return accessOK;
2893 }
2894 
getFirstSibling(const GroveImpl * grove,const::Chunk * & p) const2895 AccessResult PrologPiChunk::getFirstSibling(const GroveImpl *grove, const ::Chunk *&p) const
2896 {
2897   p = grove->root()->prolog;
2898   return accessOK;
2899 }
2900 
getFirstSibling(const GroveImpl * grove,const::Chunk * & p) const2901 AccessResult EpilogPiChunk::getFirstSibling(const GroveImpl *grove, const ::Chunk *&p) const
2902 {
2903   p = grove->root()->epilog;
2904   return accessOK;
2905 }
2906 
charChunk(const SdataMapper & mapper,GroveString & str) const2907 AccessResult SdataNode::charChunk(const SdataMapper &mapper, GroveString &str) const
2908 {
2909   const StringC &name = chunk()->entity->name();
2910   const StringC &text = chunk()->entity->asInternalEntity()->string();
2911   Char *cp = (Char *)&c_;
2912   if (mapper.sdataMap(GroveString(name.data(), name.size()), GroveString(text.data(), text.size()), *cp)) {
2913     str.assign(&c_, 1);
2914     return accessOK;
2915   }
2916   else
2917     return accessNull;
2918 }
2919 
getSystemData(GroveString & str) const2920 AccessResult SdataNode::getSystemData(GroveString &str) const
2921 {
2922   setString(str, chunk()->entity->asInternalEntity()->string());
2923   return accessOK;
2924 }
2925 
add(GroveImpl & grove,const SdataEntityEvent & event)2926 void SdataNode::add(GroveImpl &grove, const SdataEntityEvent &event)
2927 {
2928   const Location &loc = event.location().origin()->parent();
2929   grove.setLocOrigin(loc.origin());
2930   SdataChunk *chunk = new (grove.allocChunk(sizeof(SdataChunk))) SdataChunk;
2931   chunk->entity = event.entity();
2932   chunk->locIndex = loc.index();
2933   grove.appendSibling(chunk);
2934 }
2935 
setNodePtrFirst(NodePtr & ptr,const BaseNode * node) const2936 AccessResult SdataChunk::setNodePtrFirst(NodePtr &ptr, const BaseNode *node)
2937      const
2938 {
2939   ptr.assign(new SdataNode(node->grove(), this));
2940   return accessOK;
2941 }
2942 
setNodePtrFirst(NodePtr & ptr,const BaseNode * node) const2943 AccessResult NonSgmlChunk::setNodePtrFirst(NodePtr &ptr, const BaseNode *node)
2944      const
2945 {
2946   ptr.assign(new NonSgmlNode(node->grove(), this));
2947   return accessOK;
2948 }
2949 
getNonSgml(unsigned long & n) const2950 AccessResult NonSgmlNode::getNonSgml(unsigned long &n) const
2951 {
2952   n = chunk()->c;
2953   return accessOK;
2954 }
2955 
charChunk(const SdataMapper &,GroveString &) const2956 AccessResult NonSgmlNode::charChunk(const SdataMapper &, GroveString &) const
2957 {
2958   return accessNull;
2959 }
2960 
add(GroveImpl & grove,const NonSgmlCharEvent & event)2961 void NonSgmlNode::add(GroveImpl &grove, const NonSgmlCharEvent &event)
2962 {
2963   grove.setLocOrigin(event.location().origin());
2964   NonSgmlChunk *chunk = new (grove.allocChunk(sizeof(NonSgmlChunk))) NonSgmlChunk;
2965   chunk->c = event.character();
2966   chunk->locIndex = event.location().index();
2967   grove.appendSibling(chunk);
2968 }
2969 
add(GroveImpl & grove,const ExternalDataEntityEvent & event)2970 void ExternalDataNode::add(GroveImpl &grove, const ExternalDataEntityEvent &event)
2971 {
2972   grove.setLocOrigin(event.location().origin());
2973   ExternalDataChunk *chunk = new (grove.allocChunk(sizeof(ExternalDataChunk))) ExternalDataChunk;
2974   chunk->entity = event.entity();
2975   chunk->locIndex = event.location().index();
2976   grove.appendSibling(chunk);
2977 }
2978 
setNodePtrFirst(NodePtr & ptr,const BaseNode * node) const2979 AccessResult ExternalDataChunk::setNodePtrFirst(NodePtr &ptr, const BaseNode *node)
2980      const
2981 {
2982   ptr.assign(new ExternalDataNode(node->grove(), this));
2983   return accessOK;
2984 }
2985 
add(GroveImpl & grove,const SubdocEntityEvent & event)2986 void SubdocNode::add(GroveImpl &grove, const SubdocEntityEvent &event)
2987 {
2988   grove.setLocOrigin(event.location().origin());
2989   SubdocChunk *chunk = new (grove.allocChunk(sizeof(SubdocChunk))) SubdocChunk;
2990   chunk->entity = event.entity();
2991   chunk->locIndex = event.location().index();
2992   grove.appendSibling(chunk);
2993 }
2994 
setNodePtrFirst(NodePtr & ptr,const BaseNode * node) const2995 AccessResult SubdocChunk::setNodePtrFirst(NodePtr &ptr, const BaseNode *node)
2996      const
2997 {
2998   ptr.assign(new SubdocNode(node->grove(), this));
2999   return accessOK;
3000 }
3001 
getSystemData(GroveString & str) const3002 AccessResult PiEntityNode::getSystemData(GroveString &str) const
3003 {
3004   setString(str, chunk()->entity->asInternalEntity()->string());
3005   return accessOK;
3006 }
3007 
add(GroveImpl & grove,const Entity * entity,const Location & loc)3008 void PiEntityNode::add(GroveImpl &grove, const Entity *entity,
3009 		       const Location &loc)
3010 {
3011   // FIXME use parent?
3012   grove.setLocOrigin(loc.origin());
3013   PiEntityChunk *chunk = new (grove.allocChunk(sizeof(PiEntityChunk))) PiEntityChunk;
3014   chunk->entity = entity;
3015   chunk->locIndex = loc.index();
3016   grove.appendSibling(chunk);
3017 }
3018 
setNodePtrFirst(NodePtr & ptr,const BaseNode * node) const3019 AccessResult PiEntityChunk::setNodePtrFirst(NodePtr &ptr, const BaseNode *node)
3020  const
3021 {
3022   ptr.assign(new PiEntityNode(node->grove(), this));
3023   return accessOK;
3024 }
3025 
getEntity(NodePtr & ptr) const3026 AccessResult EntityRefNode::getEntity(NodePtr &ptr) const
3027 {
3028   ptr.assign(new EntityNode(grove(), chunk()->entity));
3029   return accessOK;
3030 }
3031 
getEntityName(GroveString & str) const3032 AccessResult EntityRefNode::getEntityName(GroveString &str) const
3033 {
3034   setString(str, chunk()->entity->name());
3035   return accessOK;
3036 }
3037 
AttributeAsgnNode(const GroveImpl * grove,size_t attIndex)3038 AttributeAsgnNode::AttributeAsgnNode(const GroveImpl *grove,
3039 				     size_t attIndex)
3040 : BaseNode(grove),
3041   attIndex_(attIndex)
3042 {
3043 }
3044 
nextChunkSibling(NodePtr & ptr) const3045 AccessResult ChunkNode::nextChunkSibling(NodePtr &ptr) const
3046 {
3047   // The forwarding chunk has origin = 0, so it will stop
3048   // the iteration before after() can return 0.
3049   const Chunk *p = chunk_->after();
3050   while (p == grove()->completeLimit())
3051     if (!grove()->waitForMoreNodes())
3052       return accessTimeout;
3053   if (p->origin != chunk_->origin)
3054     return accessNull;
3055   return p->setNodePtrFirst(ptr, this);
3056 }
3057 
nextChunkAfter(NodePtr & nd) const3058 AccessResult ChunkNode::nextChunkAfter(NodePtr &nd) const
3059 {
3060   const Chunk *p = chunk_->after();
3061   while (p == grove()->completeLimit())
3062     if (!grove()->waitForMoreNodes())
3063       return accessTimeout;
3064   return p->setNodePtrFirst(nd, this);
3065 }
3066 
firstSibling(NodePtr & ptr) const3067 AccessResult ChunkNode::firstSibling(NodePtr &ptr) const
3068 {
3069   const Chunk *first;
3070   AccessResult ret = chunk_->getFirstSibling(grove(), first);
3071   if (ret != accessOK)
3072     return ret;
3073   return first->setNodePtrFirst(ptr, this);
3074 }
3075 
siblingsIndex(unsigned long & i) const3076 AccessResult ChunkNode::siblingsIndex(unsigned long &i) const
3077 {
3078   const Chunk *p;
3079   AccessResult ret = chunk_->getFirstSibling(grove(), p);
3080   if (ret != accessOK)
3081     return ret;
3082   i = 0;
3083   while (p != chunk_) {
3084     unsigned long tem;
3085     if (p->getFollowing(grove(), p, tem) != accessOK)
3086       CANNOT_HAPPEN();
3087     i += tem;
3088   }
3089   return accessOK;
3090 }
3091 
followSiblingRef(unsigned long i,NodePtr & ptr) const3092 AccessResult ChunkNode::followSiblingRef(unsigned long i, NodePtr &ptr) const
3093 {
3094   const Chunk *p;
3095   unsigned long count;
3096   AccessResult ret = chunk()->getFollowing(grove(), p, count);
3097   if (ret != accessOK)
3098     return ret;
3099   while (i > 0) {
3100     const Chunk *lastP = p;
3101     ret = p->getFollowing(grove(), p, count);
3102     if (ret == accessOK && count <= i)
3103       i -= count;
3104     else if (ret == accessOK || ret == accessNull) {
3105       lastP->setNodePtrFirst(ptr, this);
3106       return ptr->followSiblingRef(i - 1, ptr);
3107     }
3108     else
3109       return ret;
3110   }
3111   return p->setNodePtrFirst(ptr, this);
3112 }
3113 
getOrigin(NodePtr & ptr) const3114 AccessResult AttributeAsgnNode::getOrigin(NodePtr &ptr) const
3115 {
3116   return setNodePtrAttributeOrigin(ptr, this);
3117 }
3118 
getName(GroveString & str) const3119 AccessResult AttributeAsgnNode::getName(GroveString &str) const
3120 {
3121   setString(str, attDefList()->def(attIndex_)->name());
3122   return accessOK;
3123 }
3124 
getImplied(bool & implied) const3125 AccessResult AttributeAsgnNode::getImplied(bool &implied) const
3126 {
3127   const AttributeValue *value = attributeValue(attIndex_, *grove());
3128   implied = (value != 0 && value->text() == 0);
3129   return accessOK;
3130 }
3131 
getValue(NodeListPtr & ptr) const3132 AccessResult AttributeAsgnNode::getValue(NodeListPtr &ptr) const
3133 {
3134   return children(ptr);
3135 }
3136 
nextChunkSibling(NodePtr & ptr) const3137 AccessResult AttributeAsgnNode::nextChunkSibling(NodePtr &ptr) const
3138 {
3139   return followSiblingRef(0, ptr);
3140 }
3141 
followSiblingRef(unsigned long i,NodePtr & ptr) const3142 AccessResult AttributeAsgnNode::followSiblingRef(unsigned long i, NodePtr &ptr) const
3143 {
3144   // Do it like this to avoid overflow.
3145   if (i >= attDefList()->size() - attIndex_ - 1)
3146     return accessNull;
3147   if (canReuse(ptr))
3148     ((AttributeAsgnNode *)this)->attIndex_ += size_t(i) + 1;
3149   else
3150     ptr.assign(makeAttributeAsgnNode(grove(), attIndex_ + 1 + size_t(i)));
3151   return accessOK;
3152 }
3153 
firstSibling(NodePtr & ptr) const3154 AccessResult AttributeAsgnNode::firstSibling(NodePtr &ptr) const
3155 {
3156   if (canReuse(ptr))
3157     ((AttributeAsgnNode *)this)->attIndex_ = 0;
3158   else
3159     ptr.assign(makeAttributeAsgnNode(grove(), 0));
3160   return accessOK;
3161 }
3162 
siblingsIndex(unsigned long & i) const3163 AccessResult AttributeAsgnNode::siblingsIndex(unsigned long &i) const
3164 {
3165   i = attIndex_;
3166   return accessOK;
3167 }
3168 
accept(NodeVisitor & visitor)3169 void AttributeAsgnNode::accept(NodeVisitor &visitor)
3170 {
3171   visitor.attributeAssignment(*this);
3172 }
3173 
firstChild(NodePtr & ptr) const3174 AccessResult AttributeAsgnNode::firstChild(NodePtr &ptr) const
3175 {
3176   const AttributeValue *value = attributeValue(attIndex_, *grove());
3177   if (value) {
3178     const Text *text;
3179     const StringC *str;
3180     switch (value->info(text, str)) {
3181     case AttributeValue::tokenized:
3182       ptr.assign(makeAttributeValueTokenNode(grove(),
3183 					     (const TokenizedAttributeValue *)value,
3184 	                                     attIndex_, 0));
3185       return accessOK;
3186     case AttributeValue::cdata:
3187       {
3188 	TextIter iter(*text);
3189 	if (!CdataAttributeValueNode::skipBoring(iter))
3190 	  break;
3191 	ptr.assign(makeCdataAttributeValueNode(grove(), value,
3192 					       attIndex_, iter));
3193 	return accessOK;
3194       }
3195     default:
3196       break;
3197     }
3198   }
3199   return accessNull;
3200 }
3201 
children(NodeListPtr & ptr) const3202 AccessResult AttributeAsgnNode::children(NodeListPtr &ptr) const
3203 {
3204   const AttributeValue *value = attributeValue(attIndex_, *grove());
3205   if (value) {
3206     const Text *text;
3207     const StringC *str;
3208     switch (value->info(text, str)) {
3209     case AttributeValue::tokenized:
3210       ptr.assign(new SiblingNodeList(makeAttributeValueTokenNode(grove(),
3211 				     (const TokenizedAttributeValue *)value,
3212 				     attIndex_, 0)));
3213       return accessOK;
3214     case AttributeValue::cdata:
3215       {
3216 	TextIter iter(*text);
3217 	if (!CdataAttributeValueNode::skipBoring(iter))
3218           ptr.assign(new BaseNodeList);
3219 	else
3220 	  ptr.assign(new SiblingNodeList(makeCdataAttributeValueNode(grove(), value,
3221 								     attIndex_, iter)));
3222 	return accessOK;
3223       }
3224     default:
3225       break;
3226     }
3227   }
3228   return accessNull;
3229 }
3230 
getTokenSep(Char & ch) const3231 AccessResult AttributeAsgnNode::getTokenSep(Char &ch) const
3232 {
3233   const AttributeValue *value = attributeValue(attIndex_, *grove());
3234   if (!value)
3235     return accessNull;
3236   const Text *text;
3237   const StringC *str;
3238   if (value->info(text, str) != AttributeValue::tokenized)
3239     return accessNull;
3240   const TokenizedAttributeValue *tValue =
3241     (const TokenizedAttributeValue *)value;
3242   if (tValue->nTokens() <= 1)
3243     return accessNull;
3244   const Char *ptr;
3245   size_t len;
3246   tValue->token(0, ptr, len);
3247   // the character following the token is a space
3248   ch = ptr[len];
3249   return accessOK;
3250 }
3251 
tokens(GroveString & s) const3252 AccessResult AttributeAsgnNode::tokens(GroveString &s) const
3253 {
3254   const AttributeValue *value = attributeValue(attIndex_, *grove());
3255   if (!value)
3256     return accessNull;
3257   const Text *text;
3258   const StringC *str;
3259   if (value->info(text, str) != AttributeValue::tokenized)
3260     return accessNull;
3261   setString(s, *str);
3262   return accessOK;
3263 }
3264 
same(const BaseNode & node) const3265 bool AttributeAsgnNode::same(const BaseNode &node) const
3266 {
3267   return node.same2(this);
3268 }
3269 
same2(const AttributeAsgnNode * node) const3270 bool AttributeAsgnNode::same2(const AttributeAsgnNode *node)
3271  const
3272 {
3273   return (attributeOriginId() == node->attributeOriginId()
3274 	  && attIndex_ == node->attIndex_);
3275 }
3276 
hash() const3277 unsigned long AttributeAsgnNode::hash() const
3278 {
3279   unsigned long n = (unsigned long)attributeOriginId();
3280   return secondHash(n + attIndex_);
3281 }
3282 
3283 ElementAttributeAsgnNode
ElementAttributeAsgnNode(const GroveImpl * grove,size_t attIndex,const ElementChunk * chunk)3284 ::ElementAttributeAsgnNode(const GroveImpl *grove, size_t attIndex,
3285 			   const ElementChunk *chunk)
3286 : AttributeAsgnNode(grove, attIndex), ElementAttributeOrigin(chunk)
3287 {
3288 }
3289 
3290 EntityAttributeAsgnNode
EntityAttributeAsgnNode(const GroveImpl * grove,size_t attIndex,const ExternalDataEntity * entity)3291 ::EntityAttributeAsgnNode(const GroveImpl *grove, size_t attIndex,
3292 			  const ExternalDataEntity *entity)
3293 : AttributeAsgnNode(grove, attIndex), EntityAttributeOrigin(entity)
3294 {
3295 }
3296 
3297 CdataAttributeValueNode
CdataAttributeValueNode(const GroveImpl * grove,const AttributeValue * value,size_t attIndex,const TextIter & iter,size_t charIndex)3298 ::CdataAttributeValueNode(const GroveImpl *grove,
3299 			  const AttributeValue *value,
3300 			  size_t attIndex,
3301 			  const TextIter &iter,
3302 			  size_t charIndex)
3303 : BaseNode(grove),
3304   value_(value),
3305   attIndex_(attIndex),
3306   iter_(iter),
3307   charIndex_(charIndex)
3308 {
3309 }
3310 
skipBoring(TextIter & iter)3311 bool CdataAttributeValueNode::skipBoring(TextIter &iter)
3312 {
3313   while (iter.valid()) {
3314     switch (iter.type()) {
3315     case TextItem::data:
3316     case TextItem::cdata:
3317     case TextItem::sdata:
3318       {
3319 	size_t length;
3320 	iter.chars(length);
3321 	if (length > 0)
3322 	  return 1;
3323       }
3324       // fall through
3325     default:
3326       iter.advance();
3327       break;
3328     }
3329   }
3330   return 0;
3331 }
3332 
getParent(NodePtr & ptr) const3333 AccessResult CdataAttributeValueNode::getParent(NodePtr &ptr) const
3334 {
3335   ptr.assign(makeAttributeAsgnNode(grove(), attIndex_));
3336   return accessOK;
3337 }
3338 
charChunk(const SdataMapper & mapper,GroveString & str) const3339 AccessResult CdataAttributeValueNode::charChunk(const SdataMapper &mapper, GroveString &str) const
3340 {
3341   if (iter_.type() == TextItem::sdata) {
3342     const Entity *entity = iter_.location().origin()->asEntityOrigin()->entity();
3343     const StringC &name = entity->name();
3344     const StringC &text = entity->asInternalEntity()->string();
3345     Char *cp = (Char *)&c_;
3346     if (mapper.sdataMap(GroveString(name.data(), name.size()), GroveString(text.data(), text.size()), *cp)) {
3347       str.assign(&c_, 1);
3348       return accessOK;
3349     }
3350     else
3351       return accessNull;
3352   }
3353   size_t len;
3354   const Char *s = iter_.chars(len);
3355   str.assign(s + charIndex_, len - charIndex_);
3356   return accessOK;
3357 }
3358 
siblingsIndex(unsigned long & n) const3359 AccessResult CdataAttributeValueNode::siblingsIndex(unsigned long &n) const
3360 {
3361   TextIter copy(iter_);
3362   size_t tem;
3363   const Char *iterChars = iter_.chars(tem);
3364   copy.rewind();
3365   skipBoring(copy);
3366   n = 0;
3367   while (copy.chars(tem) != iterChars) {
3368     if (copy.type() == TextItem::sdata)
3369       n += 1;
3370     else
3371       n += tem;
3372     copy.advance();
3373     skipBoring(copy);
3374   }
3375   n += charIndex_;
3376   return accessOK;
3377 }
3378 
getEntity(NodePtr & ptr) const3379 AccessResult CdataAttributeValueNode::getEntity(NodePtr &ptr) const
3380 {
3381   if (iter_.type() != TextItem::sdata)
3382     return accessNotInClass;
3383   const Entity *entity
3384     = iter_.location().origin()->asEntityOrigin()->entity();
3385   ptr.assign(new EntityNode(grove(), entity));
3386   return accessOK;
3387 }
3388 
getEntityName(GroveString & str) const3389 AccessResult CdataAttributeValueNode::getEntityName(GroveString &str) const
3390 {
3391   if (iter_.type() != TextItem::sdata)
3392     return accessNotInClass;
3393   const Entity *entity
3394     = iter_.location().origin()->asEntityOrigin()->entity();
3395   setString(str, entity->name());
3396   return accessOK;
3397 }
3398 
getSystemData(GroveString & str) const3399 AccessResult CdataAttributeValueNode::getSystemData(GroveString &str) const
3400 {
3401   if (iter_.type() != TextItem::sdata)
3402     return accessNotInClass;
3403   size_t len;
3404   const Char *ptr = iter_.chars(len);
3405   str.assign(ptr, len);
3406   return accessOK;
3407 }
3408 
firstSibling(NodePtr & ptr) const3409 AccessResult CdataAttributeValueNode::firstSibling(NodePtr &ptr) const
3410 {
3411   TextIter copy(iter_);
3412   copy.rewind();
3413   skipBoring(copy);
3414   if (canReuse(ptr)) {
3415     CdataAttributeValueNode *node = (CdataAttributeValueNode *)this;
3416     node->iter_ = copy;
3417     node->charIndex_ = 0;
3418   }
3419   else
3420     ptr.assign(makeCdataAttributeValueNode(grove(), value_, attIndex_, copy));
3421   return accessOK;
3422 }
3423 
nextChunkSibling(NodePtr & ptr) const3424 AccessResult CdataAttributeValueNode::nextChunkSibling(NodePtr &ptr) const
3425 {
3426   TextIter copy(iter_);
3427   copy.advance();
3428   if (!skipBoring(copy))
3429     return accessNull;
3430   if (canReuse(ptr)) {
3431     CdataAttributeValueNode *node = (CdataAttributeValueNode *)this;
3432     node->iter_ = copy;
3433     node->charIndex_ = 0;
3434   }
3435   else
3436     ptr.assign(makeCdataAttributeValueNode(grove(), value_, attIndex_, copy));
3437   return accessOK;
3438 }
3439 
nextSibling(NodePtr & ptr) const3440 AccessResult CdataAttributeValueNode::nextSibling(NodePtr &ptr) const
3441 {
3442   if (iter_.type() != TextItem::sdata) {
3443     size_t length;
3444     iter_.chars(length);
3445     if (charIndex_ + 1 < length) {
3446       if (canReuse(ptr))
3447 	((CdataAttributeValueNode *)this)->charIndex_ += 1;
3448       else
3449 	ptr.assign(makeCdataAttributeValueNode(grove(), value_,
3450 					       attIndex_, iter_,
3451 					       charIndex_ + 1));
3452       return accessOK;
3453     }
3454   }
3455   return CdataAttributeValueNode::nextChunkSibling(ptr);
3456 }
3457 
getLocation(Location & loc) const3458 AccessResult CdataAttributeValueNode::getLocation(Location &loc) const
3459 {
3460   if (iter_.type() == TextItem::sdata)
3461     return grove()->proxifyLocation(iter_.location().origin()->parent(), loc);
3462   else
3463     return grove()->proxifyLocation(iter_.location(), loc);
3464 }
3465 
accept(NodeVisitor & visitor)3466 void CdataAttributeValueNode::accept(NodeVisitor &visitor)
3467 {
3468   if (iter_.type() == TextItem::sdata)
3469     visitor.sdata(*this);
3470   else
3471     visitor.dataChar(*this);
3472 }
3473 
hash() const3474 unsigned long CdataAttributeValueNode::hash() const
3475 {
3476   unsigned long n;
3477   CdataAttributeValueNode::siblingsIndex(n);
3478   return secondHash(secondHash((unsigned long)attributeOriginId() + attIndex_) + n);
3479 }
3480 
classDef() const3481 const ClassDef &CdataAttributeValueNode::classDef() const
3482 {
3483   if (iter_.type() == TextItem::sdata)
3484     return ClassDef::sdata;
3485   else
3486     return ClassDef::dataChar;
3487 }
3488 
same(const BaseNode & node) const3489 bool CdataAttributeValueNode::same(const BaseNode &node) const
3490 {
3491   return node.same2(this);
3492 }
3493 
same2(const CdataAttributeValueNode * node) const3494 bool CdataAttributeValueNode::same2(const CdataAttributeValueNode *node)
3495      const
3496 {
3497   size_t tem;
3498   return (attributeOriginId() == node->attributeOriginId()
3499 	  && attIndex_ == node->attIndex_
3500 	  && charIndex_ == node->charIndex_
3501 	  && iter_.chars(tem) == node->iter_.chars(tem));
3502 }
3503 
chunkContains(const Node & node) const3504 bool CdataAttributeValueNode::chunkContains(const Node &node) const
3505 {
3506   if (!sameGrove(node))
3507     return 0;
3508   return ((const BaseNode &)node).inChunk(this);
3509 }
3510 
inChunk(const CdataAttributeValueNode * node) const3511 bool CdataAttributeValueNode::inChunk(const CdataAttributeValueNode *node) const
3512 {
3513   size_t tem;
3514   return (attributeOriginId() == node->attributeOriginId()
3515           && attIndex_ == node->attIndex_
3516 	  && iter_.chars(tem) == node->iter_.chars(tem)
3517 	  && charIndex_ >= node->charIndex_);
3518 }
3519 
3520 ElementCdataAttributeValueNode
ElementCdataAttributeValueNode(const GroveImpl * grove,const AttributeValue * value,size_t attIndex,const TextIter & iter,size_t charIndex,const ElementChunk * chunk)3521 ::ElementCdataAttributeValueNode(const GroveImpl *grove,
3522 				 const AttributeValue *value,
3523 				 size_t attIndex,
3524 				 const TextIter &iter,
3525 				 size_t charIndex,
3526 				 const ElementChunk *chunk)
3527 : CdataAttributeValueNode(grove, value, attIndex, iter, charIndex),
3528   ElementAttributeOrigin(chunk)
3529 {
3530 }
3531 
3532 EntityCdataAttributeValueNode
EntityCdataAttributeValueNode(const GroveImpl * grove,const AttributeValue * value,size_t attIndex,const TextIter & iter,size_t charIndex,const ExternalDataEntity * entity)3533 ::EntityCdataAttributeValueNode(const GroveImpl *grove,
3534 				const AttributeValue *value,
3535 				size_t attIndex,
3536 				const TextIter &iter,
3537 				size_t charIndex,
3538 				const ExternalDataEntity *entity)
3539 : CdataAttributeValueNode(grove, value, attIndex, iter, charIndex),
3540   EntityAttributeOrigin(entity)
3541 {
3542 }
3543 
3544 AttributeValueTokenNode
AttributeValueTokenNode(const GroveImpl * grove,const TokenizedAttributeValue * value,size_t attIndex,size_t tokenIndex)3545 ::AttributeValueTokenNode(const GroveImpl *grove,
3546 			  const TokenizedAttributeValue *value,
3547 			  size_t attIndex, size_t tokenIndex)
3548 : BaseNode(grove),
3549   value_(value),
3550   attIndex_(attIndex),
3551   tokenIndex_(tokenIndex)
3552 {
3553 }
3554 
getParent(NodePtr & ptr) const3555 AccessResult AttributeValueTokenNode::getParent(NodePtr &ptr) const
3556 {
3557   ptr.assign(makeAttributeAsgnNode(grove(), attIndex_));
3558   return accessOK;
3559 }
3560 
nextChunkSibling(NodePtr & ptr) const3561 AccessResult AttributeValueTokenNode::nextChunkSibling(NodePtr &ptr) const
3562 {
3563   return followSiblingRef(0, ptr);
3564 }
3565 
followSiblingRef(unsigned long i,NodePtr & ptr) const3566 AccessResult AttributeValueTokenNode::followSiblingRef(unsigned long i, NodePtr &ptr) const
3567 {
3568   // Do it like this to avoid possibility of overflow
3569   if (i >= value_->nTokens() - tokenIndex_ - 1)
3570     return accessNull;
3571   if (canReuse(ptr)) {
3572     AttributeValueTokenNode *node = (AttributeValueTokenNode *)this;
3573     node->tokenIndex_ += size_t(i) + 1;
3574   }
3575   else
3576     ptr.assign(makeAttributeValueTokenNode(grove(), value_, attIndex_,
3577 					   tokenIndex_ + size_t(i) + 1));
3578   return accessOK;
3579 }
3580 
firstSibling(NodePtr & ptr) const3581 AccessResult AttributeValueTokenNode::firstSibling(NodePtr &ptr) const
3582 {
3583   if (canReuse(ptr))
3584     ((AttributeValueTokenNode *)this)->tokenIndex_ = 0;
3585   else
3586     ptr.assign(makeAttributeValueTokenNode(grove(), value_, attIndex_, 0));
3587   return accessOK;
3588 }
3589 
siblingsIndex(unsigned long & i) const3590 AccessResult AttributeValueTokenNode::siblingsIndex(unsigned long &i) const
3591 {
3592   i = tokenIndex_;
3593   return accessOK;
3594 }
3595 
getToken(GroveString & str) const3596 AccessResult AttributeValueTokenNode::getToken(GroveString &str) const
3597 {
3598   const Char *ptr;
3599   size_t len;
3600   value_->token(tokenIndex_, ptr, len);
3601   str.assign(ptr, len);
3602   return accessOK;
3603 }
3604 
getEntity(NodePtr & ptr) const3605 AccessResult AttributeValueTokenNode::getEntity(NodePtr &ptr) const
3606 {
3607    if (!attDefList()->def(attIndex_)->isEntity())
3608     return accessNull;
3609   StringC token(value_->token(tokenIndex_));
3610   const Entity *entity = grove()->governingDtd()->lookupEntityTemp(0, token);
3611   if (!entity) {
3612     entity = grove()->lookupDefaultedEntity(token);
3613     if (!entity)
3614       return accessNull;
3615   }
3616   ptr.assign(new EntityNode(grove(), entity));
3617   return accessOK;
3618 }
3619 
getNotation(NodePtr & ptr) const3620 AccessResult AttributeValueTokenNode::getNotation(NodePtr &ptr) const
3621 {
3622   if (!attDefList()->def(attIndex_)->isNotation())
3623     return accessNull;
3624   StringC token(value_->token(tokenIndex_));
3625   const Notation *notation = grove()->governingDtd()->lookupNotationTemp(token);
3626   if (!notation)
3627     return accessNull;
3628   ptr.assign(new NotationNode(grove(), notation));
3629   return accessOK;
3630 }
3631 
getReferent(NodePtr & ptr) const3632 AccessResult AttributeValueTokenNode::getReferent(NodePtr &ptr) const
3633 {
3634   if (!attDefList()->def(attIndex_)->isIdref())
3635     return accessNull;
3636   StringC token(value_->token(tokenIndex_));
3637   for (;;) {
3638     Boolean complete = grove()->complete();
3639     const ElementChunk *element = grove()->lookupElement(token);
3640     if (element) {
3641       ptr.assign(new ElementNode(grove(), element));
3642       break;
3643     }
3644     if (complete)
3645       return accessNull;
3646     if (!grove()->waitForMoreNodes())
3647       return accessTimeout;
3648   }
3649   return accessOK;
3650 }
3651 
accept(NodeVisitor & visitor)3652 void AttributeValueTokenNode::accept(NodeVisitor &visitor)
3653 {
3654   visitor.attributeValueToken(*this);
3655 }
3656 
hash() const3657 unsigned long AttributeValueTokenNode::hash() const
3658 {
3659   return secondHash(secondHash((unsigned long)attributeOriginId() + attIndex_) + tokenIndex_);
3660 }
3661 
same(const BaseNode & node) const3662 bool AttributeValueTokenNode::same(const BaseNode &node) const
3663 {
3664   return node.same2(this);
3665 }
3666 
same2(const AttributeValueTokenNode * node) const3667 bool AttributeValueTokenNode::same2(const AttributeValueTokenNode *node) const
3668 {
3669   return (attributeOriginId() == node->attributeOriginId()
3670 	  && attIndex_ == node->attIndex_
3671 	  && tokenIndex_ == node->tokenIndex_);
3672 }
3673 
getLocation(Location & loc) const3674 AccessResult AttributeValueTokenNode::getLocation(Location &loc) const
3675 {
3676   const ConstPtr<Origin> *originP;
3677   Index index;
3678   if (!value_->tokenLocation(tokenIndex_, originP, index)
3679       && originP->pointer()) {
3680     loc = Location(new GroveImplProxyOrigin(grove(), originP->pointer()), index);
3681     return accessOK;
3682   }
3683   return accessNull;
3684 }
3685 
3686 ElementAttributeValueTokenNode
ElementAttributeValueTokenNode(const GroveImpl * grove,const TokenizedAttributeValue * value,size_t attIndex,size_t tokenIndex,const ElementChunk * chunk)3687 ::ElementAttributeValueTokenNode(const GroveImpl *grove,
3688 				 const TokenizedAttributeValue *value,
3689 				 size_t attIndex,
3690 				 size_t tokenIndex,
3691 				 const ElementChunk *chunk)
3692 : AttributeValueTokenNode(grove, value, attIndex, tokenIndex),
3693   ElementAttributeOrigin(chunk)
3694 {
3695 }
3696 
3697 EntityAttributeValueTokenNode
EntityAttributeValueTokenNode(const GroveImpl * grove,const TokenizedAttributeValue * value,size_t attIndex,size_t tokenIndex,const ExternalDataEntity * entity)3698 ::EntityAttributeValueTokenNode(const GroveImpl *grove,
3699 				const TokenizedAttributeValue *value,
3700 				size_t attIndex,
3701 				size_t tokenIndex,
3702 				const ExternalDataEntity *entity)
3703 : AttributeValueTokenNode(grove, value, attIndex, tokenIndex),
3704   EntityAttributeOrigin(entity)
3705 {
3706 }
3707 
EntityNode(const GroveImpl * grove,const Entity * entity)3708 EntityNode::EntityNode(const GroveImpl *grove, const Entity *entity)
3709 : BaseNode(grove), entity_(entity)
3710 {
3711 }
3712 
getOrigin(NodePtr & ptr) const3713 AccessResult EntityNode::getOrigin(NodePtr &ptr) const
3714 {
3715   if (entity_->defaulted() && grove()->lookupDefaultedEntity(entity_->name()))
3716     ptr.assign(new SgmlDocumentNode(grove(), grove()->root()));
3717   else
3718     ptr.assign(new DocumentTypeNode(grove(), grove()->governingDtd()));
3719   return accessOK;
3720 }
3721 
getOriginToSubnodeRelPropertyName(ComponentName::Id & name) const3722 AccessResult EntityNode::getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const
3723 {
3724   if (entity_->defaulted() && grove()->lookupDefaultedEntity(entity_->name()))
3725     name = ComponentName::idDefaultedEntities;
3726   else
3727     name = ComponentName::idGeneralEntities;
3728   return accessOK;
3729 }
3730 
getName(GroveString & str) const3731 AccessResult EntityNode::getName(GroveString &str) const
3732 {
3733   setString(str, entity_->name());
3734   return accessOK;
3735 }
3736 
getExternalId(NodePtr & ptr) const3737 AccessResult EntityNode::getExternalId(NodePtr &ptr) const
3738 {
3739   const ExternalEntity *x = entity_->asExternalEntity();
3740   if (!x)
3741     return accessNull;
3742   ptr.assign(new EntityExternalIdNode(grove(), x));
3743   return accessOK;
3744 }
3745 
getNotation(NodePtr & ptr) const3746 AccessResult EntityNode::getNotation(NodePtr &ptr) const
3747 {
3748   const ExternalDataEntity *x = entity_->asExternalDataEntity();
3749   if (!x || !x->notation())
3750     return accessNull;
3751   ptr.assign(new NotationNode(grove(), x->notation()));
3752   return accessOK;
3753 }
3754 
getNotationName(GroveString & str) const3755 AccessResult EntityNode::getNotationName(GroveString &str) const
3756 {
3757   const ExternalDataEntity *x = entity_->asExternalDataEntity();
3758   if (!x || !x->notation())
3759     return accessNull;
3760   setString(str, x->notation()->name());
3761   return accessOK;
3762 }
3763 
getText(GroveString & str) const3764 AccessResult EntityNode::getText(GroveString &str) const
3765 {
3766   const InternalEntity *i = entity_->asInternalEntity();
3767   if (!i)
3768     return accessNull;
3769   setString(str, i->string());
3770   return accessOK;
3771 }
3772 
getEntityType(EntityType & entityType) const3773 AccessResult EntityNode::getEntityType(EntityType &entityType) const
3774 {
3775   switch (entity_->dataType()) {
3776   case EntityDecl::sgmlText:
3777     entityType = text;
3778     break;
3779   case EntityDecl::pi:
3780     entityType = pi;
3781     break;
3782   case EntityDecl::cdata:
3783     entityType = cdata;
3784     break;
3785   case EntityDecl::sdata:
3786     entityType = sdata;
3787     break;
3788   case EntityDecl::ndata:
3789     entityType = ndata;
3790     break;
3791   case EntityDecl::subdoc:
3792     entityType = subdocument;
3793     break;
3794   default:
3795     CANNOT_HAPPEN();
3796   }
3797   return accessOK;
3798 }
3799 
getDefaulted(bool & dflted) const3800 AccessResult EntityNode::getDefaulted(bool &dflted) const
3801 {
3802   dflted = entity_->defaulted();
3803   return accessOK;
3804 }
3805 
getAttributes(NamedNodeListPtr & ptr) const3806 AccessResult EntityNode::getAttributes(NamedNodeListPtr &ptr) const
3807 {
3808   const ExternalDataEntity *x = entity_->asExternalDataEntity();
3809   if (!x)
3810     return accessNull;
3811   ptr.assign(new EntityAttributesNamedNodeList(grove(), x));
3812   return accessOK;
3813 }
3814 
attributeRef(unsigned long i,NodePtr & ptr) const3815 AccessResult EntityNode::attributeRef(unsigned long i, NodePtr &ptr) const
3816 {
3817   const ExternalDataEntity *x = entity_->asExternalDataEntity();
3818   if (!x || i >= x->attributes().size())
3819     return accessNull;
3820   ptr.assign(new EntityAttributeAsgnNode(grove(), size_t(i), x));
3821   return accessOK;
3822 }
3823 
getLocation(Location & loc) const3824 AccessResult EntityNode::getLocation(Location &loc) const
3825 {
3826   return grove()->proxifyLocation(entity_->defLocation(), loc);
3827 }
3828 
same(const BaseNode & node) const3829 bool EntityNode::same(const BaseNode &node) const
3830 {
3831   return node.same2(this);
3832 }
3833 
same2(const EntityNode * node) const3834 bool EntityNode::same2(const EntityNode *node) const
3835 {
3836   return entity_ == node->entity_;
3837 }
3838 
accept(NodeVisitor & visitor)3839 void EntityNode::accept(NodeVisitor &visitor)
3840 {
3841   visitor.entity(*this);
3842 }
3843 
hash() const3844 unsigned long EntityNode::hash() const
3845 {
3846   return (unsigned long)entity_;
3847 }
3848 
3849 EntityAttributeOrigin
EntityAttributeOrigin(const ExternalDataEntity * entity)3850 ::EntityAttributeOrigin(const ExternalDataEntity *entity)
3851 : entity_(entity)
3852 {
3853 }
3854 
3855 const AttributeDefinitionList *
attDefList() const3856 EntityAttributeOrigin::attDefList() const
3857 {
3858   return entity_->notation()->attributeDefTemp();
3859 }
3860 
3861 
3862 const AttributeValue *
attributeValue(size_t attIndex,const GroveImpl &) const3863 EntityAttributeOrigin::attributeValue(size_t attIndex, const GroveImpl &) const
3864 {
3865   return entity_->attributes().value(attIndex);
3866 }
3867 
3868 AccessResult
setNodePtrAttributeOrigin(NodePtr & ptr,const BaseNode * node) const3869 EntityAttributeOrigin::setNodePtrAttributeOrigin(NodePtr &ptr,
3870 						 const BaseNode *node) const
3871 {
3872   ptr.assign(new EntityNode(node->grove(), entity_));
3873   return accessOK;
3874 }
3875 
3876 Node *EntityAttributeOrigin
makeCdataAttributeValueNode(const GroveImpl * grove,const AttributeValue * value,size_t attIndex,const TextIter & iter,size_t charIndex) const3877 ::makeCdataAttributeValueNode(const GroveImpl *grove,
3878 			      const AttributeValue *value,
3879 			      size_t attIndex,
3880 			      const TextIter &iter,
3881 			      size_t charIndex) const
3882 {
3883   return new EntityCdataAttributeValueNode(grove, value, attIndex, iter,
3884 					   charIndex, entity_);
3885 }
3886 
3887 
3888 Node *EntityAttributeOrigin
makeAttributeValueTokenNode(const GroveImpl * grove,const TokenizedAttributeValue * value,size_t attIndex,size_t tokenIndex) const3889 ::makeAttributeValueTokenNode(const GroveImpl *grove,
3890 			      const TokenizedAttributeValue *value,
3891 			      size_t attIndex,
3892 			      size_t tokenIndex) const
3893 {
3894   return new EntityAttributeValueTokenNode(grove, value, attIndex,
3895 					   tokenIndex, entity_);
3896 }
3897 
3898 Node *EntityAttributeOrigin
makeAttributeAsgnNode(const GroveImpl * grove,size_t attIndex) const3899 ::makeAttributeAsgnNode(const GroveImpl *grove,
3900 			size_t attIndex) const
3901 {
3902   return new EntityAttributeAsgnNode(grove, attIndex, entity_);
3903 }
3904 
attributeOriginId() const3905 const void *EntityAttributeOrigin::attributeOriginId() const
3906 {
3907   return entity_;
3908 }
3909 
3910 DoctypesAndLinktypesNamedNodeList
DoctypesAndLinktypesNamedNodeList(const GroveImpl * grove)3911 ::DoctypesAndLinktypesNamedNodeList(const GroveImpl *grove)
3912 : BaseNamedNodeList(grove, grove->generalSubstTable())
3913 {
3914 }
3915 
nodeList() const3916 NodeListPtr DoctypesAndLinktypesNamedNodeList::nodeList() const
3917 {
3918   NodePtr tem(new DocumentTypeNode(grove(), grove()->governingDtd()));
3919   return new SiblingNodeList(tem);
3920 }
3921 
3922 AccessResult
3923 DoctypesAndLinktypesNamedNodeList
namedNodeU(const StringC & str,NodePtr & ptr) const3924 ::namedNodeU(const StringC &str, NodePtr &ptr) const
3925 {
3926   if (grove()->governingDtd()->name() != str)
3927     return accessNull;
3928   ptr.assign(new DocumentTypeNode(grove(), grove()->governingDtd()));
3929   return accessOK;
3930 }
3931 
3932 GeneralEntitiesNamedNodeList
GeneralEntitiesNamedNodeList(const GroveImpl * grove,const Dtd * dtd)3933 ::GeneralEntitiesNamedNodeList(const GroveImpl *grove, const Dtd *dtd)
3934 : BaseNamedNodeList(grove, grove->entitySubstTable()), dtd_(dtd)
3935 {
3936 }
3937 
nodeList() const3938 NodeListPtr GeneralEntitiesNamedNodeList::nodeList() const
3939 {
3940   return new EntitiesNodeList(grove(),
3941 			      dtd_->generalEntityIter());
3942 }
3943 
3944 AccessResult
namedNodeU(const StringC & str,NodePtr & ptr) const3945 GeneralEntitiesNamedNodeList::namedNodeU(const StringC &str, NodePtr &ptr) const
3946 {
3947   const Entity *entity
3948    = dtd_->lookupEntityTemp(0, str);
3949   if (!entity)
3950     return accessNull;
3951   ptr.assign(new EntityNode(grove(), entity));
3952   return accessOK;
3953 }
3954 
3955 AccessResult
namedNodeU(const StringC & str,NodePtr & ptr) const3956 DefaultedEntitiesNamedNodeList::namedNodeU(const StringC &str, NodePtr &ptr) const
3957 {
3958   const Entity *entity
3959    = grove()->lookupDefaultedEntity(str);
3960   if (!entity)
3961     return accessNull;
3962   ptr.assign(new EntityNode(grove(), entity));
3963   return accessOK;
3964 }
3965 
3966 NodeListPtr
nodeList() const3967 DefaultedEntitiesNamedNodeList::nodeList() const
3968 {
3969   return new EntitiesNodeList(grove(), grove()->defaultedEntityIter());
3970 }
3971 
nodeList() const3972 NodeListPtr DocEntitiesNamedNodeList::nodeList() const
3973 {
3974   return new DocEntitiesNodeList(grove());
3975 }
3976 
3977 AccessResult
namedNodeU(const StringC & str,NodePtr & ptr) const3978 DocEntitiesNamedNodeList::namedNodeU(const StringC &str, NodePtr &ptr) const
3979 {
3980   const Entity *entity
3981    = grove()->governingDtd()->lookupEntityTemp(0, str);
3982   // How I hate the default entity.
3983   while (!entity) {
3984     if (!grove()->hasDefaultEntity())
3985       return accessNull;
3986     // Make sure that the value of complete
3987     // we look at is that before we looked up
3988     // the entity.
3989     Boolean complete = grove()->complete();
3990     entity = grove()->lookupDefaultedEntity(str);
3991     if (entity)
3992       break;
3993     if (complete)
3994       return accessNull;
3995     if (!grove()->waitForMoreNodes())
3996       return accessTimeout;
3997   }
3998   ptr.assign(new EntityNode(grove(), entity));
3999   return accessOK;
4000 }
4001 
4002 AccessResult
namedNodeU(const StringC & str,NodePtr & ptr) const4003 ElementsNamedNodeList::namedNodeU(const StringC &str, NodePtr &ptr) const
4004 {
4005   for (;;) {
4006     Boolean complete = grove()->complete();
4007     const ElementChunk *element = grove()->lookupElement(str);
4008     if (element) {
4009       ptr.assign(new ElementNode(grove(), element));
4010       break;
4011     }
4012     if (complete)
4013       return accessNull;
4014     if (!grove()->waitForMoreNodes())
4015       return accessTimeout;
4016   }
4017   return accessOK;
4018 }
4019 
nodeList() const4020 NodeListPtr ElementsNamedNodeList::nodeList() const
4021 {
4022   return new ElementsNodeList(grove(), grove()->root()->documentElement);
4023 }
4024 
ElementsNodeList(const GroveImpl * grove,const Chunk * first)4025 ElementsNodeList::ElementsNodeList(const GroveImpl *grove,
4026 				   const Chunk *first)
4027 : grove_(grove), first_(first)
4028 {
4029 }
4030 
first(NodePtr & ptr) const4031 AccessResult ElementsNodeList::first(NodePtr &ptr) const
4032 {
4033   const Chunk *p = first_;
4034   while (p) {
4035     while (p == grove_->completeLimit()) {
4036       if (!grove_->waitForMoreNodes())
4037 	return accessTimeout;
4038     }
4039     if (p->id()) {
4040       ((ElementsNodeList *)this)->first_ = p;
4041       ptr.assign(new ElementNode(grove_, (const ElementChunk *)p));
4042       return accessOK;
4043     }
4044     p = p->after();
4045   }
4046   return accessNull;
4047 }
4048 
chunkRest(NodeListPtr & ptr) const4049 AccessResult ElementsNodeList::chunkRest(NodeListPtr &ptr) const
4050 {
4051   const Chunk *p = first_;
4052   while (p) {
4053     while (p == grove_->completeLimit()) {
4054       if (!grove_->waitForMoreNodes())
4055 	return accessTimeout;
4056     }
4057     if (p->id()) {
4058       if (canReuse(ptr))
4059 	((ElementsNodeList *)this)->first_ = p->after();
4060       else
4061 	ptr.assign(new ElementsNodeList(grove_, p->after()));
4062       return accessOK;
4063     }
4064     p = p->after();
4065  }
4066  return accessNull;
4067 }
4068 
4069 // iter.next() gives first member of list that this represents
4070 
EntitiesNodeList(const GroveImpl * grove,const Dtd::ConstEntityIter & iter)4071 EntitiesNodeList::EntitiesNodeList(const GroveImpl *grove,
4072 				   const Dtd::ConstEntityIter &iter)
4073 : grove_(grove), iter_(iter)
4074 {
4075 }
4076 
first(NodePtr & ptr) const4077 AccessResult EntitiesNodeList::first(NodePtr &ptr) const
4078 {
4079   Dtd::ConstEntityIter tem(iter_);
4080   const Entity *entity = tem.nextTemp();
4081   if (!entity)
4082     return accessNull;
4083   ptr.assign(new EntityNode(grove_, entity));
4084   return accessOK;
4085 }
4086 
chunkRest(NodeListPtr & ptr) const4087 AccessResult EntitiesNodeList::chunkRest(NodeListPtr &ptr) const
4088 {
4089   if (canReuse(ptr)) {
4090     EntitiesNodeList *list = (EntitiesNodeList *)this;
4091     if (list->iter_.nextTemp() == 0)
4092       return accessNull;
4093     return accessOK;
4094   }
4095   Dtd::ConstEntityIter tem(iter_);
4096   if (tem.nextTemp() == 0)
4097     return accessNull;
4098   ptr.assign(new EntitiesNodeList(grove_, tem));
4099   return accessOK;
4100 }
4101 
DocEntitiesNodeList(const GroveImpl * grove)4102 DocEntitiesNodeList::DocEntitiesNodeList(const GroveImpl *grove)
4103 : EntitiesNodeList(grove, grove->governingDtd()->generalEntityIter())
4104 {
4105 }
4106 
first(NodePtr & ptr) const4107 AccessResult DocEntitiesNodeList::first(NodePtr &ptr) const
4108 {
4109   AccessResult ret = EntitiesNodeList::first(ptr);
4110   if (ret != accessNull || !grove()->hasDefaultEntity())
4111     return ret;
4112   while (!grove()->complete())
4113     if (!grove()->waitForMoreNodes())
4114       return accessTimeout;
4115   Dtd::ConstEntityIter tem(grove()->defaultedEntityIter());
4116   const Entity *entity = tem.nextTemp();
4117   if (!entity)
4118     return accessNull;
4119   ptr.assign(new EntityNode(grove(), entity));
4120   return accessOK;
4121 }
4122 
chunkRest(NodeListPtr & ptr) const4123 AccessResult DocEntitiesNodeList::chunkRest(NodeListPtr &ptr) const
4124 {
4125   AccessResult ret = EntitiesNodeList::chunkRest(ptr);
4126   if (ret != accessNull || !grove()->hasDefaultEntity())
4127     return ret;
4128   while (!grove()->complete())
4129     if (!grove()->waitForMoreNodes())
4130       return accessTimeout;
4131   Dtd::ConstEntityIter tem(grove()->defaultedEntityIter());
4132   const Entity *entity = tem.nextTemp();
4133   if (!entity)
4134     return accessNull;
4135   ptr.assign(new EntitiesNodeList(grove(), tem));
4136   return accessOK;
4137 }
4138 
4139 NotationsNamedNodeList
NotationsNamedNodeList(const GroveImpl * grove,const Dtd * dtd)4140 ::NotationsNamedNodeList(const GroveImpl *grove, const Dtd *dtd)
4141 : BaseNamedNodeList(grove, grove->generalSubstTable()), dtd_(dtd)
4142 {
4143 }
4144 
nodeList() const4145 NodeListPtr NotationsNamedNodeList::nodeList() const
4146 {
4147   return new NotationsNodeList(grove(),
4148 			       dtd_->notationIter());
4149 }
4150 
4151 AccessResult
namedNodeU(const StringC & str,NodePtr & ptr) const4152 NotationsNamedNodeList::namedNodeU(const StringC &str, NodePtr &ptr) const
4153 {
4154   const Notation *notation
4155    = dtd_->lookupNotationTemp(str);
4156   if (!notation)
4157     return accessNull;
4158   ptr.assign(new NotationNode(grove(), notation));
4159   return accessOK;
4160 }
4161 
4162 
4163 // iter.next() gives first member of list that this represents
4164 
NotationsNodeList(const GroveImpl * grove,const Dtd::ConstNotationIter & iter)4165 NotationsNodeList::NotationsNodeList(const GroveImpl *grove,
4166 				     const Dtd::ConstNotationIter &iter)
4167 : grove_(grove), iter_(iter)
4168 {
4169 }
4170 
first(NodePtr & ptr) const4171 AccessResult NotationsNodeList::first(NodePtr &ptr) const
4172 {
4173   Dtd::ConstNotationIter tem(iter_);
4174   const Notation *notation = tem.nextTemp();
4175   if (!notation)
4176     return accessNull;
4177   ptr.assign(new NotationNode(grove_, notation));
4178   return accessOK;
4179 }
4180 
chunkRest(NodeListPtr & ptr) const4181 AccessResult NotationsNodeList::chunkRest(NodeListPtr &ptr) const
4182 {
4183   if (canReuse(ptr)) {
4184     NotationsNodeList *list = (NotationsNodeList *)this;
4185     if (list->iter_.next().isNull())
4186       return accessNull;
4187     return accessOK;
4188   }
4189   Dtd::ConstNotationIter tem(iter_);
4190   if (tem.nextTemp() == 0)
4191     return accessNull;
4192   ptr.assign(new NotationsNodeList(grove_, tem));
4193   return accessOK;
4194 }
4195 
NotationNode(const GroveImpl * grove,const Notation * notation)4196 NotationNode::NotationNode(const GroveImpl *grove,
4197 			   const Notation *notation)
4198 : BaseNode(grove), notation_(notation)
4199 {
4200 }
4201 
getOrigin(NodePtr & ptr) const4202 AccessResult NotationNode::getOrigin(NodePtr &ptr) const
4203 {
4204   ptr.assign(new DocumentTypeNode(grove(), grove()->governingDtd()));
4205   return accessOK;
4206 }
4207 
getName(GroveString & str) const4208 AccessResult NotationNode::getName(GroveString &str) const
4209 {
4210   setString(str, notation_->name());
4211   return accessOK;
4212 }
4213 
getExternalId(NodePtr & ptr) const4214 AccessResult NotationNode::getExternalId(NodePtr &ptr) const
4215 {
4216   ptr.assign(new NotationExternalIdNode(grove(), notation_));
4217   return accessOK;
4218 }
4219 
getLocation(Location & loc) const4220 AccessResult NotationNode::getLocation(Location &loc) const
4221 {
4222   return grove()->proxifyLocation(notation_->defLocation(), loc);
4223 }
4224 
same(const BaseNode & node) const4225 bool NotationNode::same(const BaseNode &node) const
4226 {
4227   return node.same2(this);
4228 }
4229 
same2(const NotationNode * node) const4230 bool NotationNode::same2(const NotationNode *node) const
4231 {
4232   return notation_ == node->notation_;
4233 }
4234 
accept(NodeVisitor & visitor)4235 void NotationNode::accept(NodeVisitor &visitor)
4236 {
4237   visitor.notation(*this);
4238 }
4239 
hash() const4240 unsigned long NotationNode::hash() const
4241 {
4242   return (unsigned long)notation_;
4243 }
4244 
ExternalIdNode(const GroveImpl * grove)4245 ExternalIdNode::ExternalIdNode(const GroveImpl *grove)
4246 : BaseNode(grove)
4247 {
4248 }
4249 
getPublicId(GroveString & str) const4250 AccessResult ExternalIdNode::getPublicId(GroveString &str) const
4251 {
4252   const StringC *s = externalId().publicIdString();
4253   if (!s)
4254     return accessNull;
4255   setString(str, *s);
4256   return accessOK;
4257 }
4258 
getSystemId(GroveString & str) const4259 AccessResult ExternalIdNode::getSystemId(GroveString &str) const
4260 {
4261   const StringC *s = externalId().systemIdString();
4262   if (!s)
4263     return accessNull;
4264   setString(str, *s);
4265   return accessOK;
4266 }
4267 
getGeneratedSystemId(GroveString & str) const4268 AccessResult ExternalIdNode::getGeneratedSystemId(GroveString &str) const
4269 {
4270   const StringC &s = externalId().effectiveSystemId();
4271   if (!s.size())
4272     return accessNull;
4273   setString(str, s);
4274   return accessOK;
4275 }
4276 
accept(NodeVisitor & visitor)4277 void ExternalIdNode::accept(NodeVisitor &visitor)
4278 {
4279   visitor.externalId(*this);
4280 }
4281 
same(const BaseNode & node) const4282 bool ExternalIdNode::same(const BaseNode &node) const
4283 {
4284   return node.same2(this);
4285 }
4286 
same2(const ExternalIdNode * node) const4287 bool ExternalIdNode::same2(const ExternalIdNode *node) const
4288 {
4289   return &externalId() == &node->externalId();
4290 }
4291 
EntityExternalIdNode(const GroveImpl * grove,const ExternalEntity * entity)4292 EntityExternalIdNode::EntityExternalIdNode(const GroveImpl *grove,
4293 					   const ExternalEntity *entity)
4294 : ExternalIdNode(grove), entity_(entity)
4295 {
4296 }
4297 
externalId() const4298 const ExternalId &EntityExternalIdNode::externalId() const
4299 {
4300   return entity_->externalId();
4301 }
4302 
getOrigin(NodePtr & ptr) const4303 AccessResult EntityExternalIdNode::getOrigin(NodePtr &ptr) const
4304 {
4305   ptr.assign(new EntityNode(grove(), entity_));
4306   return accessOK;
4307 }
4308 
hash() const4309 unsigned long EntityExternalIdNode::hash() const
4310 {
4311   return secondHash((unsigned long)entity_);
4312 }
4313 
NotationExternalIdNode(const GroveImpl * grove,const Notation * notation)4314 NotationExternalIdNode::NotationExternalIdNode(const GroveImpl *grove,
4315 					       const Notation *notation)
4316 : ExternalIdNode(grove), notation_(notation)
4317 {
4318 }
4319 
externalId() const4320 const ExternalId &NotationExternalIdNode::externalId() const
4321 {
4322   return notation_->externalId();
4323 }
4324 
getOrigin(NodePtr & ptr) const4325 AccessResult NotationExternalIdNode::getOrigin(NodePtr &ptr) const
4326 {
4327   ptr.assign(new NotationNode(grove(), notation_));
4328   return accessOK;
4329 }
4330 
hash() const4331 unsigned long NotationExternalIdNode::hash() const
4332 {
4333   return secondHash((unsigned long)notation_);
4334 }
4335 
getParent(NodePtr & ptr) const4336 AccessResult ChunkNode::getParent(NodePtr &ptr) const
4337 {
4338   if (!chunk_->origin)
4339     return accessNull;
4340   // This is needed because PiNodes in the prolog and
4341   // epilog don't have a parent but do have an origin.
4342   // Also for the document element.
4343   if ((const Chunk *)chunk()->origin == grove()->root())
4344     return accessNull;
4345   chunk_->origin->setNodePtrFirst(ptr, this);
4346   return accessOK;
4347 }
4348 
getTreeRoot(NodePtr & ptr) const4349 AccessResult ChunkNode::getTreeRoot(NodePtr &ptr) const
4350 {
4351   if (chunk()->origin
4352       && (const Chunk *)chunk()->origin != grove()->root()
4353       // With invalid documents we might have elements in the epilog
4354       && !grove()->root()->epilog
4355       && grove()->root()->documentElement)
4356     return grove()->root()->documentElement->setNodePtrFirst(ptr, this);
4357   return Node::getTreeRoot(ptr);
4358 }
4359 
getOrigin(NodePtr & ptr) const4360 AccessResult ChunkNode::getOrigin(NodePtr &ptr) const
4361 {
4362   if (!chunk_->origin)
4363     return accessNull;
4364   chunk_->origin->setNodePtrFirst(ptr, this);
4365   return accessOK;
4366 }
4367 
getOriginToSubnodeRelPropertyName(ComponentName::Id & name) const4368 AccessResult ChunkNode::getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const
4369 {
4370   if ((const Chunk *)chunk()->origin != grove()->root())
4371     name = ComponentName::idContent;
4372   else if ((const Chunk *)chunk() == grove()->root()->documentElement)
4373     name = ComponentName::idDocumentElement;
4374   else {
4375     const Chunk *tem;
4376     if (chunk()->getFirstSibling(grove(), tem) == accessOK && tem == grove()->root()->prolog)
4377       name = ComponentName::idProlog;
4378     else
4379       name = ComponentName::idEpilog;
4380   }
4381   return accessOK;
4382 }
4383 
hash() const4384 unsigned long ChunkNode::hash() const
4385 {
4386   return (unsigned long)chunk_;
4387 }
4388 
same(const BaseNode & node) const4389 bool ChunkNode::same(const BaseNode &node) const
4390 {
4391   return node.same2(this);
4392 }
4393 
same2(const ChunkNode * node) const4394 bool ChunkNode::same2(const ChunkNode *node) const
4395 {
4396   return chunk_ == node->chunk_;
4397 }
4398 
~BaseNode()4399 BaseNode::~BaseNode()
4400 {
4401 }
4402 
addRef()4403 void BaseNode::addRef()
4404 {
4405   ++refCount_;
4406 }
4407 
release()4408 void BaseNode::release()
4409 {
4410   ASSERT(refCount_ != 0);
4411   if (--refCount_ == 0)
4412     delete this;
4413 }
4414 
groveIndex() const4415 unsigned BaseNode::groveIndex() const
4416 {
4417   return grove_->groveIndex();
4418 }
4419 
operator ==(const Node & node) const4420 bool BaseNode::operator==(const Node &node) const
4421 {
4422   if (!sameGrove(node))
4423     return 0;
4424   return same((const BaseNode &)node);
4425 }
4426 
chunkContains(const Node & node) const4427 bool BaseNode::chunkContains(const Node &node) const
4428 {
4429   if (!sameGrove(node))
4430     return 0;
4431   return same((const BaseNode &)node);
4432 }
4433 
inChunk(const DataNode *) const4434 bool BaseNode::inChunk(const DataNode *) const
4435 {
4436   return 0;
4437 }
4438 
inChunk(const CdataAttributeValueNode *) const4439 bool BaseNode::inChunk(const CdataAttributeValueNode *) const
4440 {
4441   return 0;
4442 }
4443 
same2(const ChunkNode *) const4444 bool BaseNode::same2(const ChunkNode *) const
4445 {
4446   return 0;
4447 }
4448 
same2(const DataNode *) const4449 bool BaseNode::same2(const DataNode *) const
4450 {
4451   return 0;
4452 }
4453 
same2(const AttributeAsgnNode *) const4454 bool BaseNode::same2(const AttributeAsgnNode *) const
4455 {
4456   return 0;
4457 }
4458 
same2(const AttributeValueTokenNode *) const4459 bool BaseNode::same2(const AttributeValueTokenNode *) const
4460 {
4461   return 0;
4462 }
4463 
same2(const CdataAttributeValueNode *) const4464 bool BaseNode::same2(const CdataAttributeValueNode *) const
4465 {
4466   return 0;
4467 }
4468 
same2(const EntityNode *) const4469 bool BaseNode::same2(const EntityNode *) const
4470 {
4471   return 0;
4472 }
4473 
same2(const NotationNode *) const4474 bool BaseNode::same2(const NotationNode *) const
4475 {
4476   return 0;
4477 }
4478 
same2(const ExternalIdNode *) const4479 bool BaseNode::same2(const ExternalIdNode *) const
4480 {
4481   return 0;
4482 }
4483 
same2(const DocumentTypeNode *) const4484 bool BaseNode::same2(const DocumentTypeNode *) const
4485 {
4486   return 0;
4487 }
4488 
same2(const SgmlConstantsNode *) const4489 bool BaseNode::same2(const SgmlConstantsNode *) const
4490 {
4491   return 0;
4492 }
4493 
same2(const MessageNode *) const4494 bool BaseNode::same2(const MessageNode *) const
4495 {
4496   return 0;
4497 }
4498 
nextSibling(NodePtr & ptr) const4499 AccessResult BaseNode::nextSibling(NodePtr &ptr) const
4500 {
4501   return nextChunkSibling(ptr);
4502 }
4503 
follow(NodeListPtr & ptr) const4504 AccessResult BaseNode::follow(NodeListPtr &ptr) const
4505 {
4506   NodePtr nd;
4507   AccessResult ret = nextSibling(nd);
4508   switch (ret) {
4509   case accessOK:
4510     ptr.assign(new SiblingNodeList(nd));
4511     break;
4512   case accessNull:
4513     ptr.assign(new BaseNodeList);
4514     ret = accessOK;
4515     break;
4516   default:
4517     break;
4518   }
4519   return ret;
4520 }
4521 
children(NodeListPtr & ptr) const4522 AccessResult BaseNode::children(NodeListPtr &ptr) const
4523 {
4524   NodePtr head;
4525   AccessResult ret = firstChild(head);
4526   switch (ret) {
4527   case accessOK:
4528     ptr.assign(new SiblingNodeList(head));
4529     break;
4530   case accessNull:
4531     ptr.assign(new BaseNodeList);
4532     ret = accessOK;
4533     break;
4534   default:
4535     break;
4536   }
4537   return ret;
4538 }
4539 
getOrigin(NodePtr & ptr) const4540 AccessResult BaseNode::getOrigin(NodePtr &ptr) const
4541 {
4542   return getParent(ptr);
4543 }
4544 
getGroveRoot(NodePtr & ptr) const4545 AccessResult BaseNode::getGroveRoot(NodePtr &ptr) const
4546 {
4547   ptr.assign(new SgmlDocumentNode(grove(), grove()->root()));
4548   return accessOK;
4549 }
4550 
getLocation(Location &) const4551 AccessResult BaseNode::getLocation(Location &) const
4552 {
4553   return accessNull;
4554 }
4555 
queryInterface(IID iid,const void * & p) const4556 bool BaseNode::queryInterface(IID iid, const void *&p) const
4557 {
4558   if (iid == LocNode::iid) {
4559     const LocNode *ip = this;
4560     p = ip;
4561     return 1;
4562   }
4563   return 0;
4564 }
4565 
4566 AccessResult
setNodePtrFirst(NodePtr & ptr,const BaseNode * node) const4567 ForwardingChunk::setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const
4568 {
4569   if (forwardTo == 0)
4570     return accessNull;
4571   ASSERT(origin == forwardTo->origin);
4572   return forwardTo->setNodePtrFirst(ptr, node);
4573 }
4574 
4575 AccessResult
getFollowing(const GroveImpl * grove,const Chunk * & p,unsigned long & nNodes) const4576 ForwardingChunk::getFollowing(const GroveImpl *grove,
4577                               const Chunk *&p, unsigned long &nNodes)
4578     const
4579 {
4580   AccessResult ret = Chunk::getFollowing(grove, p, nNodes);
4581   if (ret == accessOK)
4582     nNodes = 0;
4583   return ret;
4584 }
4585 
4586 AccessResult
getFollowing(const GroveImpl * grove,const Chunk * & p,unsigned long & nNodes) const4587 LocOriginChunk::getFollowing(const GroveImpl *grove,
4588                              const Chunk *&p, unsigned long &nNodes)
4589     const
4590 {
4591   AccessResult ret = Chunk::getFollowing(grove, p, nNodes);
4592   if (ret == accessOK)
4593     nNodes = 0;
4594   return ret;
4595 }
4596 
setNodePtrFirst(NodePtr & ptr,const BaseNode * node) const4597 AccessResult LocOriginChunk::setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const
4598 {
4599   return ((const Chunk *)(this + 1))->setNodePtrFirst(ptr, node);
4600 }
4601 
setNodePtrFirst(NodePtr & ptr,const ElementNode * node) const4602 AccessResult LocOriginChunk::setNodePtrFirst(NodePtr &ptr, const ElementNode *node) const
4603 {
4604   return ((const Chunk *)(this + 1))->setNodePtrFirst(ptr, node);
4605 }
4606 
setNodePtrFirst(NodePtr & ptr,const DataNode * node) const4607 AccessResult LocOriginChunk::setNodePtrFirst(NodePtr &ptr, const DataNode *node) const
4608 {
4609   return ((const Chunk *)(this + 1))->setNodePtrFirst(ptr, node);
4610 }
4611 
after() const4612 const Chunk *LocOriginChunk::after() const
4613 {
4614   return this + 1;
4615 }
4616 
getLocOrigin(const Origin * & ret) const4617 Boolean LocOriginChunk::getLocOrigin(const Origin *&ret) const
4618 {
4619   ret = locOrigin;
4620   return 1;
4621 }
4622 
4623 AccessResult
setNodePtrFirst(NodePtr & ptr,const ElementNode * node) const4624 Chunk::setNodePtrFirst(NodePtr &ptr, const ElementNode *node) const
4625 {
4626   return setNodePtrFirst(ptr, (const BaseNode *)node);
4627 }
4628 
4629 AccessResult
setNodePtrFirst(NodePtr & ptr,const DataNode * node) const4630 Chunk::setNodePtrFirst(NodePtr &ptr, const DataNode *node) const
4631 {
4632   return setNodePtrFirst(ptr, (const BaseNode *)node);
4633 }
4634 
id() const4635 const StringC *Chunk::id() const
4636 {
4637   return 0;
4638 }
4639 
getFollowing(const GroveImpl * grove,const Chunk * & f,unsigned long & n) const4640 AccessResult Chunk::getFollowing(const GroveImpl *grove,
4641 			         const Chunk *&f, unsigned long &n) const
4642 {
4643   const Chunk *p = after();
4644   while (p == grove->completeLimit())
4645     if (!grove->waitForMoreNodes())
4646       return accessTimeout;
4647   if (p->origin != origin)
4648     return accessNull;
4649   n = 1;
4650   f = p;
4651   return accessOK;
4652 }
4653 
getFirstSibling(const GroveImpl * grove,const Chunk * & p) const4654 AccessResult Chunk::getFirstSibling(const GroveImpl *grove,
4655 				    const Chunk *&p) const
4656 {
4657   if ((const Chunk *)origin == grove->root())
4658     return accessNotInClass;
4659   p = origin->after();
4660   return accessOK;
4661 }
4662 
getLocOrigin(const Origin * &) const4663 Boolean Chunk::getLocOrigin(const Origin *&) const
4664 {
4665   return 0;
4666 }
4667 
4668 #ifdef SP_NAMESPACE
4669 }
4670 #endif
4671 
4672 #include "grove_inst.cxx"
4673