1
// Copyright (c) 1996, 1997 James Clark
2
// See the file COPYING for copying permission.
4
// FIXME location for SgmlDocument node.
13
#include "GroveBuilder.h"
14
#include "ErrorCountEventHandler.h"
15
#include "OutputCharStream.h"
16
#include "MessageFormatter.h"
19
#include "Attribute.h"
29
#pragma warning ( disable : 4250 ) // inherits via dominance
36
namespace SP_NAMESPACE {
39
#ifdef GROVE_NAMESPACE
40
using namespace GROVE_NAMESPACE;
43
static bool blockingAccess = 1;
45
size_t initialBlockSize = 8192;
46
unsigned maxBlocksPerSize = 20;
51
struct SgmlDocumentChunk;
58
class CdataAttributeValueNode;
59
class AttributeValueTokenNode;
60
class AttributeAsgnNode;
61
class AttributeDefNode;
65
class DocumentTypeNode;
66
class SgmlConstantsNode;
68
class ElementTypeNode;
70
class ElementTokenNode;
71
class PcdataTokenNode;
72
class DefaultEntityNode;
75
// second arg never null
76
// Set ptr to a node pointing to first Node in this.
77
virtual AccessResult setNodePtrFirst(NodePtr &ptr,
78
const BaseNode *) const = 0;
79
virtual AccessResult setNodePtrFirst(NodePtr &ptr,
80
const ElementNode *node) const;
81
virtual AccessResult setNodePtrFirst(NodePtr &ptr,
82
const DataNode *node) const;
83
virtual const Chunk *after() const = 0;
84
virtual AccessResult getFollowing(const GroveImpl *,
85
const Chunk *&, unsigned long &nNodes)
87
virtual AccessResult getFirstSibling(const GroveImpl *, const Chunk *&) const;
88
virtual const StringC *id() const;
89
virtual Boolean getLocOrigin(const Origin *&) const;
93
struct LocChunk : public Chunk {
97
struct ParentChunk : public LocChunk {
98
ParentChunk() : nextSibling(0) { }
102
class ElementChunk : public ParentChunk {
104
virtual const AttributeValue *
105
attributeValue(size_t attIndex, const GroveImpl &grove) const;
106
virtual Boolean mustOmitEndTag() const;
107
virtual Boolean included() const;
108
const AttributeDefinitionList *attDefList() const;
109
AccessResult setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const;
110
AccessResult setNodePtrFirst(NodePtr &ptr, const DataNode *node) const;
111
AccessResult setNodePtrFirst(NodePtr &ptr, const ElementNode *node) const;
112
static const StringC &key(const ElementChunk &chunk) { return *chunk.id(); }
113
const Chunk *after() const;
114
AccessResult getFollowing(const GroveImpl *, const Chunk *&, unsigned long &nNodes)
116
const ElementType *elementType() const { return type; }
118
friend class ElementNode;
119
const ElementType *type;
121
unsigned long elementIndex;
125
const AttributeDefinitionList *ElementChunk::attDefList() const
127
return type->attributeDefTemp();
130
class LocOriginChunk : public Chunk {
132
LocOriginChunk(const Origin *lo) : locOrigin(lo) { }
133
AccessResult setNodePtrFirst(NodePtr &ptr, const BaseNode *) const;
134
AccessResult setNodePtrFirst(NodePtr &ptr, const ElementNode *node) const;
135
AccessResult setNodePtrFirst(NodePtr &ptr, const DataNode *node) const;
136
const Chunk *after() const;
137
AccessResult getFollowing(const GroveImpl *,
138
const Chunk *&, unsigned long &nNodes)
140
Boolean getLocOrigin(const Origin *&) const;
142
const Origin *locOrigin;
147
MessageItem(Node::Severity severity, const StringC &text, const Location &loc)
148
: severity_(severity), text_(text), loc_(loc), next_(0) { }
149
Node::Severity severity() const { return severity_; }
150
const Location &loc() const { return loc_; }
151
const StringC &text() const { return text_; }
152
const MessageItem *next() const { return next_; }
153
MessageItem **nextP() { return &next_; }
155
Node::Severity severity_;
161
// multiple threads using const interface.
165
GroveImpl(unsigned groveIndex);
168
void addRef() const { ++(((GroveImpl *)this)->refCount_); }
169
void release() const {
170
if (!--(((GroveImpl *)this)->refCount_))
171
delete (GroveImpl *)this;
173
unsigned groveIndex() const { return groveIndex_; }
174
const SgmlDocumentChunk *root() const { return root_; }
175
const AttributeValue *impliedAttributeValue() const {
176
return impliedAttributeValue_.pointer();
178
// Return 0 if not yet available.
179
Boolean getAppinfo(const StringC *&) const;
180
const SubstTable<Char> *generalSubstTable() const {
181
return instanceSyntax_.isNull() ? 0 : instanceSyntax_->generalSubstTable();
183
const SubstTable<Char> *entitySubstTable() const {
184
return instanceSyntax_.isNull() ? 0 : instanceSyntax_->entitySubstTable();
186
// Be careful not to change ref counts while accessing DTD.
187
const Dtd *governingDtd() const { return dtd_.pointer(); }
188
// must not be called till grove is complete
189
Dtd::ConstEntityIter defaultedEntityIter() const;
190
const Entity *lookupDefaultedEntity(const StringC &) const;
191
const ElementChunk *lookupElement(const StringC &) const;
192
typedef PointerTableIter<ElementChunk *,StringC,Hash,ElementChunk> ElementIter;
193
// must not be called till grove is complete
194
ElementIter elementIter() const;
195
Boolean complete() const { return complete_; }
196
const void *completeLimit() const { return completeLimit_; }
197
const void *completeLimitWithLocChunkAfter() const {
198
return completeLimitWithLocChunkAfter_;
200
const Origin *currentLocOrigin() const { return currentLocOrigin_; }
201
Boolean hasDefaultEntity() const { return hasDefaultEntity_; }
202
Boolean maybeMoreSiblings(const ParentChunk *chunk) const;
203
// return zero for timeout
204
Boolean waitForMoreNodes() const;
205
AccessResult proxifyLocation(const Location &, Location &) const;
206
const MessageItem *messageList() const { return messageList_; }
207
// must not be called till grove is complete
208
void getSd(ConstPtr<Sd> &, ConstPtr<Syntax> &, ConstPtr<Syntax> &) const;
209
// non-const interface
210
void *allocChunk(size_t);
211
void appendSibling(Chunk *);
212
void appendSibling(DataChunk *);
213
Boolean tryExtend(size_t n) {
222
DataChunk *pendingData() { return pendingData_; }
223
void push(ElementChunk *, Boolean hasId);
225
void setAppinfo(const StringC &);
226
void setDtd(const ConstPtr<Dtd> &dtd);
227
void setSd(const ConstPtr<Sd> &, const ConstPtr<Syntax> &, const ConstPtr<Syntax> &);
228
void storeAttributeValue(const ConstPtr<AttributeValue> &value) {
229
values_.push_back(value);
231
void addDefaultedEntity(const ConstPtr<Entity> &);
233
Boolean haveRootOrigin();
234
void setLocOrigin(const ConstPtr<Origin> &);
235
void appendMessage(MessageItem *);
237
GroveImpl(const GroveImpl &);
238
void operator=(const GroveImpl &);
241
Boolean maybeMoreSiblings1(const ParentChunk *) const;
242
void *allocFinish(size_t);
245
void finishDocumentElement();
248
void storeLocOrigin(const ConstPtr<Origin> &);
251
BlockHeader() : next(0) { }
254
unsigned groveIndex_;
255
SgmlDocumentChunk *root_;
256
ParentChunk *origin_;
257
DataChunk *pendingData_;
261
ConstPtr<Syntax> prologSyntax_;
262
ConstPtr<Syntax> instanceSyntax_;
263
ConstPtr<AttributeValue> impliedAttributeValue_;
264
Vector<ConstPtr<AttributeValue> > values_;
265
Vector<ConstPtr<Origin> > origins_;
266
NamedResourceTable<Entity> defaultedEntityTable_;
267
PointerTable<ElementChunk *,StringC,Hash,ElementChunk> idTable_;
268
Boolean hasDefaultEntity_;
269
Boolean haveAppinfo_;
271
const Origin *currentLocOrigin_;
274
const void *completeLimit_;
275
const void *completeLimitWithLocChunkAfter_;
276
// pointer to first free byte in current block
278
// free bytes in current block
279
// there's space for a forwarding chunk after this if freePtr_ != 0
281
// the head of the list of blocks
282
BlockHeader *blocks_;
283
// where to store pointer to next block
284
BlockHeader **blockTailPtr_;
285
// current normal size for a block
286
size_t blockAllocSize_;
287
// number of blocks allocated at this size
288
size_t nBlocksThisSizeAlloced_;
290
mutable Condition moreNodesCondition_;
294
unsigned long nEvents_;
295
unsigned long nElements_;
296
enum { maxChunksWithoutLocOrigin = 100 };
297
unsigned nChunksSinceLocOrigin_;
298
MessageItem *messageList_;
299
MessageItem **messageListTailP_;
304
GroveImplPtr(const GroveImpl *grove) : grove_(grove) { grove_->addRef(); }
305
~GroveImplPtr() { grove_->release(); }
306
const GroveImpl *operator->() const { return grove_; }
307
operator const GroveImpl *() const { return grove_; }
309
GroveImplPtr(const GroveImplPtr &); // undefined
310
void operator=(const GroveImplPtr &); // undefined
311
const GroveImpl *grove_;
314
class GroveImplProxyOrigin : public ProxyOrigin {
316
GroveImplProxyOrigin(const GroveImpl *grove, const Origin *origin)
317
: grove_(grove), ProxyOrigin(origin) { }
322
class GroveBuilderMessageEventHandler : public ErrorCountEventHandler {
324
GroveBuilderMessageEventHandler(unsigned groveIndex, Messenger *mgr, MessageFormatter *msgFmt_);
325
~GroveBuilderMessageEventHandler();
326
void message(MessageEvent *);
327
void sgmlDecl(SgmlDeclEvent *);
328
void makeInitialRoot(NodePtr &);
329
void setSd(const ConstPtr<Sd> &, const ConstPtr<Syntax> &, const ConstPtr<Syntax> &);
334
MessageFormatter *msgFmt_;
337
class GroveBuilderEventHandler : public GroveBuilderMessageEventHandler {
339
GroveBuilderEventHandler(unsigned groveIndex, Messenger *mgr, MessageFormatter *msgFmt_);
340
void appinfo(AppinfoEvent *);
341
void startElement(StartElementEvent *);
342
void endElement(EndElementEvent *);
343
void data(DataEvent *);
344
void sdataEntity(SdataEntityEvent *);
345
void nonSgmlChar(NonSgmlCharEvent *);
346
void externalDataEntity(ExternalDataEntityEvent *);
347
void subdocEntity(SubdocEntityEvent *);
349
void endProlog(EndPrologEvent *);
350
void entityDefaulted(EntityDefaultedEvent *);
354
void setString(GroveString &to, const StringC &from)
356
to.assign(from.data(), from.size());
360
bool operator==(const StringC &str1, const GroveString &str2)
362
return (str1.size() == str2.size()
363
&& memcmp(str1.data(), str2.data(), str1.size()*sizeof(Char)) == 0);
367
bool operator!=(const StringC &str1, const GroveString &str2)
369
return !(str1 == str2);
373
size_t roundUp(size_t n)
375
return (n + (sizeof(void *) - 1)) & ~(sizeof(void *) - 1);
378
// All nodes in this grove must be derived from BaseNode.
380
class BaseNode : public Node, public LocNode {
382
BaseNode(const GroveImpl *grove);
386
bool canReuse(NodePtr &ptr) const;
387
unsigned groveIndex() const;
388
bool operator==(const Node &node) const;
389
// Implemented with double dispatching.
390
virtual bool same(const BaseNode &) const = 0;
391
// The second half of the dispatch.
392
virtual bool same2(const ChunkNode *) const;
393
virtual bool same2(const DataNode *) const;
394
virtual bool same2(const AttributeAsgnNode *) const;
395
virtual bool same2(const AttributeValueTokenNode *) const;
396
virtual bool same2(const CdataAttributeValueNode *) const;
397
virtual bool same2(const EntityNode *) const;
398
virtual bool same2(const NotationNode *) const;
399
virtual bool same2(const ExternalIdNode *) const;
400
virtual bool same2(const DocumentTypeNode *) const;
401
virtual bool same2(const SgmlConstantsNode *) const;
402
virtual bool same2(const MessageNode *) const;
403
virtual bool same2(const ElementTypeNode *) const;
404
virtual bool same2(const ModelGroupNode *) const;
405
virtual bool same2(const ElementTokenNode *) const;
406
virtual bool same2(const PcdataTokenNode *) const;
407
virtual bool same2(const AttributeDefNode *) const;
408
virtual bool same2(const DefaultEntityNode *) const;
409
const GroveImpl *grove() const { return grove_; }
410
AccessResult nextSibling(NodePtr &ptr) const;
411
AccessResult follow(NodeListPtr &ptr) const;
412
AccessResult children(NodeListPtr &) const;
413
AccessResult getOrigin(NodePtr &ptr) const;
414
AccessResult getGroveRoot(NodePtr &ptr) const;
415
AccessResult getLocation(Location &) const;
416
bool queryInterface(IID, const void *&) const;
417
bool chunkContains(const Node &) const;
418
bool inChunk(const DataNode *node) const;
419
bool inChunk(const CdataAttributeValueNode *) const;
421
static unsigned long secondHash(unsigned long n) {
430
BaseNode::BaseNode(const GroveImpl *grove)
431
: grove_(grove), refCount_(0)
436
bool BaseNode::canReuse(NodePtr &ptr) const
438
const Node *tem = &*ptr;
439
return tem == this && refCount_ == 1;
442
struct ForwardingChunk : Chunk {
443
ForwardingChunk(const Chunk *to, ParentChunk *p)
444
: forwardTo(to) { origin = p; }
445
AccessResult setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const;
446
AccessResult getFollowing(const GroveImpl *,
447
const Chunk *&, unsigned long &nNodes)
449
const Chunk *after() const { return forwardTo; }
450
const Chunk *forwardTo;
453
class ChunkNode : public BaseNode {
455
ChunkNode(const GroveImpl *grove, const LocChunk *chunk);
456
const LocChunk *chunk() const { return chunk_; }
457
bool same(const BaseNode &node) const;
458
bool same2(const ChunkNode *node) const;
459
unsigned long hash() const;
460
AccessResult getParent(NodePtr &ptr) const;
461
AccessResult getTreeRoot(NodePtr &ptr) const;
462
AccessResult getOrigin(NodePtr &) const;
463
AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &) const;
464
AccessResult nextChunkSibling(NodePtr &) const;
465
AccessResult nextChunkAfter(NodePtr &) const;
466
AccessResult firstSibling(NodePtr &) const;
467
AccessResult siblingsIndex(unsigned long &) const;
468
AccessResult followSiblingRef(unsigned long, NodePtr &) const;
469
AccessResult getLocation(Location &) const;
471
const LocChunk *chunk_; // never null
475
ChunkNode::ChunkNode(const GroveImpl *grove, const LocChunk *chunk)
476
: BaseNode(grove), chunk_(chunk)
480
class SgmlDocumentNode;
482
struct SgmlDocumentChunk : public ParentChunk {
483
SgmlDocumentChunk() : prolog(0), documentElement(0), epilog(0) { }
485
Chunk *documentElement;
487
AccessResult setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const;
488
const Chunk *after() const { return this + 1; }
491
class SgmlDocumentNode : public ChunkNode, public SdNode {
493
SgmlDocumentNode(const GroveImpl *grove,
494
const SgmlDocumentChunk *chunk);
495
void accept(NodeVisitor &visitor);
496
const ClassDef &classDef() const { return ClassDef::sgmlDocument; }
497
AccessResult getDocumentElement(NodePtr &ptr) const;
498
AccessResult getElements(NamedNodeListPtr &ptr) const;
499
AccessResult getEntities(NamedNodeListPtr &ptr) const;
500
AccessResult getDefaultedEntities(NamedNodeListPtr &ptr) const;
501
AccessResult getGoverningDoctype(NodePtr &ptr) const;
502
AccessResult getDoctypesAndLinktypes(NamedNodeListPtr &ptr) const;
503
AccessResult getProlog(NodeListPtr &ptr) const;
504
AccessResult getEpilog(NodeListPtr &ptr) const;
505
AccessResult getSgmlConstants(NodePtr &) const;
506
AccessResult getApplicationInfo(GroveString &str) const;
507
AccessResult getMessages(NodeListPtr &ptr) const;
508
AccessResult nextChunkSibling(NodePtr &) const { return accessNotInClass; }
509
AccessResult firstSibling(NodePtr &) const { return accessNotInClass; }
510
AccessResult siblingsIndex(unsigned long &) const { return accessNotInClass; }
511
AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &) const { return accessNull; }
512
AccessResult getSd(ConstPtr<Sd> &sd,
513
ConstPtr<Syntax> &prologSyntax,
514
ConstPtr<Syntax> &instanceSyntax) const;
516
const SgmlDocumentChunk *chunk() const {
517
return (const SgmlDocumentChunk *)ChunkNode::chunk();
522
SgmlDocumentNode::SgmlDocumentNode(const GroveImpl *grove,
523
const SgmlDocumentChunk *chunk)
524
: ChunkNode(grove, chunk)
528
// array of pointers to attribute values stored after chunk
530
class AttElementChunk : private ElementChunk {
532
AttElementChunk(size_t n) : nAtts(n) { }
533
friend class ElementNode;
535
const AttributeValue *
536
attributeValue(size_t attIndex, const GroveImpl &) const;
537
Boolean mustOmitEndTag() const;
538
const Chunk *after() const;
539
const StringC *id() const;
543
class IncludedElementChunk : public ElementChunk {
544
friend class ElementNode;
545
Boolean included() const;
548
class IncludedAttElementChunk : public AttElementChunk {
549
IncludedAttElementChunk(size_t n) : AttElementChunk(n) { }
550
friend class ElementNode;
551
Boolean included() const;
554
class ElementNode : public ChunkNode {
556
friend class ElementChunk;
557
ElementNode(const GroveImpl *grove, const ElementChunk *chunk)
558
: ChunkNode(grove, chunk) { }
559
AccessResult attributeRef(unsigned long i, NodePtr &ptr) const;
560
AccessResult nextChunkSibling(NodePtr &ptr) const;
561
AccessResult nextChunkAfter(NodePtr &) const;
562
AccessResult firstChild(NodePtr &ptr) const;
563
AccessResult getAttributes(NamedNodeListPtr &ptr) const;
564
AccessResult getGi(GroveString &str) const;
565
bool hasGi(GroveString) const;
566
AccessResult getId(GroveString &str) const;
567
AccessResult getContent(NodeListPtr &ptr) const;
568
AccessResult getMustOmitEndTag(bool &) const;
569
AccessResult getIncluded(bool &) const;
570
AccessResult elementIndex(unsigned long &) const;
571
AccessResult getElementType(NodePtr &) const;
572
void accept(NodeVisitor &visitor);
573
const ClassDef &classDef() const { return ClassDef::element; }
574
static void add(GroveImpl &grove, const StartElementEvent &event);
577
ElementChunk *makeAttElementChunk(GroveImpl &grove,
578
const StartElementEvent &,
580
const ElementChunk *chunk() const {
581
return (const ElementChunk *)ChunkNode::chunk();
583
void reuseFor(const ElementChunk *chunk) { chunk_ = chunk; }
586
class CharsChunk : public LocChunk {
588
const Chunk *after() const {
589
return (const Chunk *)((char *)this + allocSize(size));
591
const Char *data() const { return (const Char *)(this + 1); }
593
static size_t allocSize(size_t nChars) {
594
return roundUp(sizeof(CharsChunk) + nChars*sizeof(Char));
597
// The characters immediately follow the chunk
599
class DataChunk : public CharsChunk {
601
friend class DataNode;
602
AccessResult setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const;
603
AccessResult setNodePtrFirst(NodePtr &ptr, const ElementNode *node) const;
604
AccessResult setNodePtrFirst(NodePtr &ptr, const DataNode *node) const;
605
AccessResult getFollowing(const GroveImpl *, const Chunk *&, unsigned long &) const;
608
class DataNode : public ChunkNode {
610
friend class DataChunk;
611
DataNode(const GroveImpl *, const DataChunk *chunk, size_t index);
612
bool same(const BaseNode &node) const;
613
bool same2(const DataNode *node) const;
614
AccessResult nextSibling(NodePtr &ptr) const;
615
AccessResult nextChunkSibling(NodePtr &ptr) const;
616
AccessResult nextChunkAfter(NodePtr &) const;
617
AccessResult siblingsIndex(unsigned long &) const;
618
AccessResult followSiblingRef(unsigned long, NodePtr &) const;
619
AccessResult charChunk(const SdataMapper &, GroveString &) const;
620
bool chunkContains(const Node &) const;
621
bool inChunk(const DataNode *node) const;
622
AccessResult getNonSgml(unsigned long &) const;
623
AccessResult getLocation(Location &) const;
624
void accept(NodeVisitor &visitor);
625
const ClassDef &classDef() const { return ClassDef::dataChar; }
626
unsigned long hash() const;
627
static void add(GroveImpl &grove, const DataEvent &event);
629
const DataChunk *chunk() const {
630
return (const DataChunk *)ChunkNode::chunk();
632
void reuseFor(const DataChunk *chunk, size_t index);
637
DataNode::DataNode(const GroveImpl *grove,
638
const DataChunk *chunk, size_t index)
639
: ChunkNode(grove, chunk), index_(index)
643
class PiChunk : protected CharsChunk {
645
AccessResult setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const;
648
class PrologPiChunk : public PiChunk {
649
AccessResult getFirstSibling(const GroveImpl *, const struct Chunk *&) const;
652
class EpilogPiChunk : public PiChunk {
653
AccessResult getFirstSibling(const GroveImpl *, const struct Chunk *&) const;
656
class PiNode : public ChunkNode {
658
PiNode(const GroveImpl *grove, const PiChunk *chunk)
659
: ChunkNode(grove, chunk) {}
660
AccessResult getSystemData(GroveString &) const;
661
AccessResult getEntityName(GroveString &) const{ return accessNull; }
662
AccessResult getEntity(NodePtr &) const { return accessNull; }
663
void accept(NodeVisitor &visitor) { visitor.pi(*this); }
664
const ClassDef &classDef() const { return ClassDef::pi; }
665
static void add(GroveImpl &grove, const PiEvent &);
667
const PiChunk *chunk() const {
668
return (const PiChunk *)ChunkNode::chunk();
672
class EntityRefChunk : public LocChunk {
674
const Entity *entity;
675
const Chunk *after() const { return this + 1; }
678
class EntityRefNode : public ChunkNode {
680
EntityRefNode(const GroveImpl *grove, const EntityRefChunk *chunk)
681
: ChunkNode(grove, chunk) { }
682
AccessResult getEntity(NodePtr &) const;
683
AccessResult getEntityName(GroveString &) const;
685
const EntityRefChunk *chunk() const {
686
return (const EntityRefChunk *)ChunkNode::chunk();
692
class SdataChunk : private EntityRefChunk {
693
friend class SdataNode;
694
AccessResult setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const;
697
class SdataNode : public EntityRefNode {
699
SdataNode(const GroveImpl *grove, const SdataChunk *chunk)
700
: EntityRefNode(grove, chunk) { }
701
AccessResult charChunk(const SdataMapper &, GroveString &) const;
702
AccessResult getSystemData(GroveString &str) const;
703
void accept(NodeVisitor &visitor) { visitor.sdata(*this); }
704
const ClassDef &classDef() const { return ClassDef::sdata; }
705
static void add(GroveImpl &grove, const SdataEntityEvent &event);
712
class NonSgmlChunk : public LocChunk {
715
AccessResult setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const;
716
const Chunk *after() const { return this + 1; }
719
class NonSgmlNode : public ChunkNode {
721
NonSgmlNode(const GroveImpl *grove, const NonSgmlChunk *chunk)
722
: ChunkNode(grove, chunk) { }
723
AccessResult charChunk(const SdataMapper &, GroveString &) const;
724
AccessResult getNonSgml(unsigned long &) const;
725
void accept(NodeVisitor &visitor) { visitor.nonSgml(*this); }
726
const ClassDef &classDef() const { return ClassDef::nonSgml; }
727
static void add(GroveImpl &grove, const NonSgmlCharEvent &event);
729
const NonSgmlChunk *chunk() const {
730
return (const NonSgmlChunk *)ChunkNode::chunk();
734
class ExternalDataNode;
736
class ExternalDataChunk : private EntityRefChunk {
737
friend class ExternalDataNode;
738
AccessResult setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const;
741
class ExternalDataNode : public EntityRefNode {
743
ExternalDataNode(const GroveImpl *grove, const ExternalDataChunk *chunk)
744
: EntityRefNode(grove, chunk) { }
745
void accept(NodeVisitor &visitor) { visitor.externalData(*this); }
746
const ClassDef &classDef() const { return ClassDef::externalData; }
747
static void add(GroveImpl &grove, const ExternalDataEntityEvent &event);
750
class SubdocChunk : private EntityRefChunk {
751
friend class SubdocNode;
752
AccessResult setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const;
755
class SubdocNode : public EntityRefNode {
757
SubdocNode(const GroveImpl *grove, const SubdocChunk *chunk)
758
: EntityRefNode(grove, chunk) { }
759
void accept(NodeVisitor &visitor) { visitor.subdocument(*this); }
760
const ClassDef &classDef() const { return ClassDef::subdocument; }
761
static void add(GroveImpl &grove, const SubdocEntityEvent &event);
764
class PiEntityChunk : private EntityRefChunk {
765
friend class PiEntityNode;
766
AccessResult setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const;
769
class PiEntityNode : public EntityRefNode {
771
PiEntityNode(const GroveImpl *grove, const PiEntityChunk *chunk)
772
: EntityRefNode(grove, chunk) { }
773
AccessResult getSystemData(GroveString &) const;
774
void accept(NodeVisitor &visitor) { visitor.pi(*this); }
775
const ClassDef &classDef() const { return ClassDef::pi; }
776
static void add(GroveImpl &grove, const Entity *, const Location &);
779
struct AttributeDefOrigin {
780
AttributeDefOrigin(size_t attIndex = 0) : attIndex_(attIndex) { }
781
virtual const AttributeDefinitionList *attDefList() const = 0;
782
virtual Node *makeCdataAttributeValueNode(const GroveImpl *grove,
783
const AttributeValue *value,
785
const TextIter &iter,
786
size_t charIndex = 0) const = 0;
787
virtual Node *makeAttributeValueTokenNode(const GroveImpl *grove,
788
const TokenizedAttributeValue *value,
790
size_t tokenIndex) const = 0;
791
virtual Node *makeOriginNode(const GroveImpl *grove, size_t attIndex) const = 0;
792
virtual AccessResult makeAttributeValueNode(const GroveImpl *grove,
794
const AttributeValue *value) const;
795
virtual AccessResult makeAttributeValueNodeList(const GroveImpl *grove,
797
const AttributeValue *value) const;
798
virtual AccessResult makeAttributeDefNode(const GroveImpl *grove,
800
size_t attributeDefIdx) const = 0;
801
virtual AccessResult makeAttributeDefList(const GroveImpl *,
806
AccessResult makeAttributeDefNode(const GroveImpl *grove,
808
const StringC &name) const;
809
virtual const void *attributeOriginId() const = 0;
810
const size_t attIndex() const { return attIndex_; }
815
struct AttributeOrigin : public virtual AttributeDefOrigin {
816
virtual const AttributeValue *
817
attributeValue(size_t attIndex, const GroveImpl &grove) const = 0;
819
setNodePtrAttributeOrigin(NodePtr &, const BaseNode *) const = 0;
820
virtual Node *makeAttributeAsgnNode(const GroveImpl *grove,
821
size_t attIndex) const = 0;
824
class ElementAttributeOrigin : public virtual AttributeOrigin {
826
ElementAttributeOrigin(const ElementChunk *);
827
const AttributeDefinitionList *attDefList() const;
828
const AttributeValue *
829
attributeValue(size_t attIndex, const GroveImpl &grove) const;
830
AccessResult setNodePtrAttributeOrigin(NodePtr &, const BaseNode *) const;
831
Node *makeCdataAttributeValueNode(const GroveImpl *grove,
832
const AttributeValue *value,
834
const TextIter &iter,
835
size_t charIndex) const;
836
Node *makeAttributeValueTokenNode(const GroveImpl *grove,
837
const TokenizedAttributeValue *value,
839
size_t tokenIndex) const;
840
Node *makeAttributeAsgnNode(const GroveImpl *grove,
841
size_t attIndex) const;
842
virtual Node *makeOriginNode(const GroveImpl *grove, size_t attIndex) const;
843
virtual AccessResult makeAttributeDefNode(const GroveImpl *grove,
845
size_t attributeDefIdx) const;
846
const void *attributeOriginId() const;
848
const ElementChunk *chunk_;
851
class EntityAttributeOrigin : public virtual AttributeOrigin {
853
EntityAttributeOrigin(const ExternalDataEntity *);
854
const AttributeDefinitionList *attDefList() const;
855
const AttributeValue *
856
attributeValue(size_t attIndex, const GroveImpl &grove) const;
857
AccessResult setNodePtrAttributeOrigin(NodePtr &, const BaseNode *) const;
858
Node *makeCdataAttributeValueNode(const GroveImpl *grove,
859
const AttributeValue *value,
861
const TextIter &iter,
862
size_t charIndex) const;
863
Node *makeAttributeValueTokenNode(const GroveImpl *grove,
864
const TokenizedAttributeValue *value,
866
size_t tokenIndex) const;
867
Node *makeAttributeAsgnNode(const GroveImpl *grove,
868
size_t attIndex) const;
869
virtual AccessResult makeAttributeDefNode(const GroveImpl *grove,
871
size_t attributeDefIdx) const;
872
virtual Node *makeOriginNode(const GroveImpl *grove, size_t attIndex) const;
873
const void *attributeOriginId() const;
875
const ExternalDataEntity *entity_;
878
// CLASS DEF: ElementTypeAttributeDefOrigin
879
class ElementTypeAttributeDefOrigin : public virtual AttributeDefOrigin {
881
ElementTypeAttributeDefOrigin(const ElementType *);
882
const AttributeDefinitionList *attDefList() const;
883
Node *makeCdataAttributeValueNode(const GroveImpl *grove,
884
const AttributeValue *value,
886
const TextIter &iter,
887
size_t charIndex) const;
888
Node *makeAttributeValueTokenNode(const GroveImpl *grove,
889
const TokenizedAttributeValue *value,
891
size_t tokenIndex) const;
892
virtual AccessResult makeAttributeDefNode(const GroveImpl *grove,
894
size_t attributeDefIdx) const;
895
virtual AccessResult makeAttributeDefList(const GroveImpl *grove,
897
size_t firstAttDefIdx) const;
898
virtual Node *makeOriginNode(const GroveImpl *grove, size_t attIndex) const;
899
virtual const void *attributeOriginId() const;
901
const ElementType *elementType_;
904
// CLASS DEF: NotationAttributeDefOrigin
905
class NotationAttributeDefOrigin : public virtual AttributeDefOrigin {
907
NotationAttributeDefOrigin(const Notation *);
908
virtual const AttributeDefinitionList *attDefList() const;
909
Node *makeCdataAttributeValueNode(const GroveImpl *grove,
910
const AttributeValue *value,
912
const TextIter &iter,
913
size_t charIndex) const;
914
Node *makeAttributeValueTokenNode(const GroveImpl *grove,
915
const TokenizedAttributeValue *value,
917
size_t tokenIndex) const;
918
virtual AccessResult makeAttributeDefNode(const GroveImpl *grove,
920
size_t attributeDefIdx) const;
921
virtual AccessResult makeAttributeDefList(const GroveImpl *grove,
923
size_t firstAttDefIdx) const;
924
virtual Node *makeOriginNode(const GroveImpl *grove, size_t attIndex) const;
925
virtual const void *attributeOriginId() const;
927
const Notation *notation_;
930
class AttributeAsgnNode : public BaseNode, public virtual AttributeOrigin {
932
AttributeAsgnNode(const GroveImpl *grove, size_t attIndex);
933
AccessResult getOrigin(NodePtr &ptr) const;
934
AccessResult getName(GroveString &str) const;
935
AccessResult getImplied(bool &implied) const;
936
AccessResult getValue(NodeListPtr &ptr) const;
937
AccessResult children(NodeListPtr &ptr) const;
938
AccessResult firstChild(NodePtr &ptr) const;
939
AccessResult nextChunkSibling(NodePtr &ptr) const;
940
AccessResult followSiblingRef(unsigned long, NodePtr &) const;
941
AccessResult firstSibling(NodePtr &) const;
942
AccessResult siblingsIndex(unsigned long &) const;
943
AccessResult getTokenSep(Char &) const;
944
AccessResult tokens(GroveString &) const;
945
AccessResult getAttributeDef(NodePtr &) const;
946
void accept(NodeVisitor &visitor);
947
const ClassDef &classDef() const { return ClassDef::attributeAssignment; }
948
AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
949
name = ComponentName::idAttributes;
952
bool same(const BaseNode &node) const;
953
bool same2(const AttributeAsgnNode *node) const;
954
unsigned long hash() const;
957
class ElementAttributeAsgnNode
958
: public AttributeAsgnNode, public ElementAttributeOrigin {
960
ElementAttributeAsgnNode(const GroveImpl *grove, size_t attIndex,
961
const ElementChunk *);
964
class EntityAttributeAsgnNode
965
: public AttributeAsgnNode, public EntityAttributeOrigin {
967
EntityAttributeAsgnNode(const GroveImpl *grove, size_t attIndex,
968
const ExternalDataEntity *);
971
class AttributeValueTokenNode
972
: public BaseNode, public virtual AttributeDefOrigin {
974
AttributeValueTokenNode(const GroveImpl *grove,
975
const TokenizedAttributeValue *value,
978
AccessResult getParent(NodePtr &ptr) const;
979
AccessResult nextChunkSibling(NodePtr &ptr) const;
980
AccessResult followSiblingRef(unsigned long, NodePtr &ptr) const;
981
AccessResult firstSibling(NodePtr &) const;
982
AccessResult siblingsIndex(unsigned long &) const;
983
AccessResult getToken(GroveString &str) const;
984
AccessResult getEntity(NodePtr &ptr) const;
985
AccessResult getNotation(NodePtr &ptr) const;
986
AccessResult getReferent(NodePtr &ptr) const;
987
AccessResult getLocation(Location &) const;
988
void accept(NodeVisitor &visitor);
989
const ClassDef &classDef() const { return ClassDef::attributeValueToken; }
990
AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
991
name = ComponentName::idValue;
994
bool same(const BaseNode &node) const;
995
bool same2(const AttributeValueTokenNode *node) const;
996
unsigned long hash() const;
998
const TokenizedAttributeValue *value_;
1002
class ElementAttributeValueTokenNode
1003
: public AttributeValueTokenNode, public ElementAttributeOrigin {
1005
ElementAttributeValueTokenNode(const GroveImpl *grove,
1006
const TokenizedAttributeValue *value,
1009
const ElementChunk *);
1012
class EntityAttributeValueTokenNode
1013
: public AttributeValueTokenNode, public EntityAttributeOrigin {
1015
EntityAttributeValueTokenNode(const GroveImpl *grove,
1016
const TokenizedAttributeValue *value,
1019
const ExternalDataEntity *);
1022
class ElementTypeAttributeValueTokenNode
1023
: public AttributeValueTokenNode, public ElementTypeAttributeDefOrigin {
1025
ElementTypeAttributeValueTokenNode(const GroveImpl *grove,
1026
const TokenizedAttributeValue *value,
1029
const ElementType *);
1030
AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
1031
name = ComponentName::idDefaultValue;
1036
class NotationAttributeValueTokenNode
1037
: public AttributeValueTokenNode, public NotationAttributeDefOrigin {
1039
NotationAttributeValueTokenNode(const GroveImpl *grove,
1040
const TokenizedAttributeValue *value,
1044
AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
1045
name = ComponentName::idDefaultValue;
1050
class CdataAttributeValueNode
1051
: public BaseNode, public virtual AttributeDefOrigin {
1053
static bool skipBoring(TextIter &iter);
1054
CdataAttributeValueNode(const GroveImpl *grove,
1055
const AttributeValue *value,
1057
const TextIter &iter,
1059
AccessResult getParent(NodePtr &ptr) const;
1060
AccessResult charChunk(const SdataMapper &, GroveString &) const;
1061
bool chunkContains(const Node &) const;
1062
bool inChunk(const CdataAttributeValueNode *) const;
1063
AccessResult getEntity(NodePtr &) const;
1064
AccessResult getEntityName(GroveString &) const;
1065
AccessResult getSystemData(GroveString &str) const;
1066
AccessResult nextSibling(NodePtr &ptr) const;
1067
AccessResult nextChunkSibling(NodePtr &ptr) const;
1068
AccessResult firstSibling(NodePtr &) const;
1069
AccessResult siblingsIndex(unsigned long &) const;
1070
AccessResult getLocation(Location &) const;
1071
void accept(NodeVisitor &visitor);
1072
const ClassDef &classDef() const;
1073
AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
1074
name = ComponentName::idValue;
1077
bool same(const BaseNode &node) const;
1078
bool same2(const CdataAttributeValueNode *node) const;
1079
unsigned long hash() const;
1081
const AttributeValue *value_;
1082
TextIter iter_; // must be valid
1087
class ElementCdataAttributeValueNode
1088
: public CdataAttributeValueNode, public ElementAttributeOrigin {
1090
ElementCdataAttributeValueNode(const GroveImpl *grove,
1091
const AttributeValue *value,
1093
const TextIter &iter,
1095
const ElementChunk *);
1098
class EntityCdataAttributeValueNode
1099
: public CdataAttributeValueNode, public EntityAttributeOrigin {
1101
EntityCdataAttributeValueNode(const GroveImpl *grove,
1102
const AttributeValue *value,
1104
const TextIter &iter,
1106
const ExternalDataEntity *);
1109
class ElementTypeCdataAttributeValueNode
1110
: public CdataAttributeValueNode, public ElementTypeAttributeDefOrigin {
1112
ElementTypeCdataAttributeValueNode(const GroveImpl *grove,
1113
const AttributeValue *value,
1115
const TextIter &iter,
1117
const ElementType *);
1118
AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
1119
name = ComponentName::idDefaultValue;
1124
class NotationCdataAttributeValueNode
1125
: public CdataAttributeValueNode, public NotationAttributeDefOrigin {
1127
NotationCdataAttributeValueNode(const GroveImpl *grove,
1128
const AttributeValue *value,
1130
const TextIter &iter,
1133
AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
1134
name = ComponentName::idDefaultValue;
1139
class EntityNodeBase : public BaseNode {
1141
EntityNodeBase(const GroveImpl *grove, const Entity *entity)
1142
: BaseNode(grove), entity_(entity) {}
1143
AccessResult getName(GroveString &str) const;
1144
AccessResult getExternalId(NodePtr &ptr) const;
1145
AccessResult getNotation(NodePtr &) const;
1146
AccessResult getNotationName(GroveString &) const;
1147
AccessResult getText(GroveString &) const;
1148
AccessResult getEntityType(Node::EntityType::Enum &) const;
1149
AccessResult getAttributes(NamedNodeListPtr &) const;
1150
AccessResult attributeRef(unsigned long i, NodePtr &ptr) const;
1151
AccessResult getLocation(Location &) const;
1152
unsigned long hash() const;
1154
const Entity *entity_;
1157
class EntityNode : public EntityNodeBase {
1159
EntityNode(const GroveImpl *grove, const Entity *entity);
1160
AccessResult getOrigin(NodePtr &ptr) const;
1161
AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &) const;
1162
AccessResult getDefaulted(bool &) const;
1163
bool same(const BaseNode &) const;
1164
bool same2(const EntityNode *) const;
1165
void accept(NodeVisitor &);
1166
const ClassDef &classDef() const { return ClassDef::entity; }
1169
class DefaultEntityNode : public EntityNodeBase {
1171
DefaultEntityNode(const GroveImpl *grove, const Entity *entity);
1172
AccessResult getOrigin(NodePtr &ptr) const;
1173
AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &) const;
1174
bool same(const BaseNode &) const;
1175
bool same2(const DefaultEntityNode *) const;
1176
void accept(NodeVisitor &);
1177
const ClassDef &classDef() const { return ClassDef::defaultEntity; }
1180
class NotationNode : public BaseNode {
1182
NotationNode(const GroveImpl *grove, const Notation *notation);
1183
AccessResult getOrigin(NodePtr &ptr) const;
1184
AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
1185
name = ComponentName::idNotations;
1188
AccessResult getName(GroveString &str) const;
1189
AccessResult getExternalId(NodePtr &ptr) const;
1190
AccessResult getAttributeDefs(NamedNodeListPtr &) const;
1191
bool same(const BaseNode &) const;
1192
bool same2(const NotationNode *) const;
1193
AccessResult getLocation(Location &) const;
1194
void accept(NodeVisitor &);
1195
const ClassDef &classDef() const { return ClassDef::notation; }
1196
unsigned long hash() const;
1198
const Notation *notation_;
1201
class ExternalIdNode : public BaseNode {
1203
ExternalIdNode(const GroveImpl *grove);
1204
virtual const ExternalId &externalId() const = 0;
1205
AccessResult getPublicId(GroveString &) const;
1206
AccessResult getSystemId(GroveString &) const;
1207
AccessResult getGeneratedSystemId(GroveString &) const;
1208
void accept(NodeVisitor &);
1209
const ClassDef &classDef() const { return ClassDef::externalId; }
1210
AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
1211
name = ComponentName::idExternalId;
1214
bool same(const BaseNode &) const;
1215
bool same2(const ExternalIdNode *) const;
1218
class EntityExternalIdNode : public ExternalIdNode {
1220
EntityExternalIdNode(const GroveImpl *grove,
1221
const ExternalEntity *entity);
1222
const ExternalId &externalId() const;
1223
AccessResult getOrigin(NodePtr &ptr) const;
1224
unsigned long hash() const;
1226
const ExternalEntity *entity_;
1229
class NotationExternalIdNode : public ExternalIdNode {
1231
NotationExternalIdNode(const GroveImpl *grove,
1232
const Notation *notation);
1233
const ExternalId &externalId() const;
1234
AccessResult getOrigin(NodePtr &ptr) const;
1235
unsigned long hash() const;
1237
const Notation *notation_;
1240
class DocumentTypeNode : public BaseNode {
1242
DocumentTypeNode(const GroveImpl *grove, const Dtd *);
1243
AccessResult getName(GroveString &) const;
1244
AccessResult getGoverning(bool &) const;
1245
AccessResult getGeneralEntities(NamedNodeListPtr &) const;
1246
AccessResult getNotations(NamedNodeListPtr &) const;
1247
AccessResult getElementTypes(NamedNodeListPtr &) const;
1248
AccessResult getDefaultEntity(NodePtr &) const;
1249
AccessResult getParameterEntities(NamedNodeListPtr &) const;
1250
AccessResult getOrigin(NodePtr &) const;
1251
AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
1252
name = ComponentName::idDoctypesAndLinktypes;
1255
AccessResult nextChunkSibling(NodePtr &) const;
1256
void accept(NodeVisitor &);
1257
const ClassDef &classDef() const { return ClassDef::documentType; }
1258
bool same(const BaseNode &) const;
1259
bool same2(const DocumentTypeNode *) const;
1264
class SgmlConstantsNode : public BaseNode {
1266
SgmlConstantsNode(const GroveImpl *);
1267
AccessResult getOrigin(NodePtr &) const;
1268
void accept(NodeVisitor &);
1269
const ClassDef &classDef() const { return ClassDef::sgmlConstants; }
1270
AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
1271
name = ComponentName::idSgmlConstants;
1274
bool same(const BaseNode &) const;
1275
bool same2(const SgmlConstantsNode *) const;
1278
class MessageNode : public BaseNode {
1280
MessageNode(const GroveImpl *, const MessageItem *);
1281
AccessResult getOrigin(NodePtr &) const;
1282
AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
1283
name = ComponentName::noId;
1286
AccessResult nextChunkSibling(NodePtr &) const;
1287
AccessResult firstSibling(NodePtr &) const;
1288
AccessResult siblingsIndex(unsigned long &) const;
1289
void accept(NodeVisitor &);
1290
const ClassDef &classDef() const { return ClassDef::message; }
1291
bool same(const BaseNode &) const;
1292
bool same2(const MessageNode *) const;
1293
AccessResult getLocation(Location &) const;
1294
AccessResult getText(GroveString &) const;
1295
AccessResult getSeverity(Severity &) const;
1297
const MessageItem *item_;
1300
// CLASS DEF: ElementTypeNode
1301
class ElementTypeNode : public BaseNode {
1303
ElementTypeNode(const GroveImpl *grove, const ElementType &elementType)
1304
: BaseNode(grove), elementType_(elementType) {};
1305
AccessResult getOrigin(NodePtr &) const;
1306
const ClassDef &classDef() const { return ClassDef::elementType; }
1307
AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
1308
name = ComponentName::idElementTypes;
1311
AccessResult getGi(GroveString &str) const;
1312
AccessResult getAttributeDefs(NamedNodeListPtr &) const;
1313
AccessResult getContentType(Node::ContentType::Enum &) const;
1314
AccessResult getExclusions(GroveStringListPtr &) const;
1315
AccessResult getInclusions(GroveStringListPtr &) const;
1316
AccessResult getModelGroup(NodePtr &) const;
1317
AccessResult getOmitEndTag(bool &) const;
1318
AccessResult getOmitStartTag(bool &) const;
1319
AccessResult getLocation(Location &) const;
1320
bool same(const BaseNode &) const;
1321
bool same2(const ElementTypeNode *) const;
1322
void accept(NodeVisitor &);
1323
unsigned long hash() const;
1324
const ElementType &elementType() const { return elementType_; }
1326
const ElementType &elementType_;
1329
// CLASS DEF: ContentTokenNodeBase
1330
class ModelGroupNode;
1331
class ContentTokenNodeBase : public BaseNode {
1333
ContentTokenNodeBase(const GroveImpl *grove,
1334
const ElementType &elementType,
1335
ModelGroupNode *parentModelGroupNode = 0);
1336
~ContentTokenNodeBase();
1337
AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
1338
name = ComponentName::idContentTokens;
1341
AccessResult getOrigin(NodePtr &) const;
1342
AccessResult getLocation(Location &) const;
1343
const ElementType &elementType() const { return elementType_; }
1345
ModelGroupNode *parentModelGroupNode_;
1346
const ElementType &elementType_;
1349
// CLASS DEF: ElementTokenNode
1350
class ElementTokenNode : public ContentTokenNodeBase {
1352
ElementTokenNode(const GroveImpl *grove,
1353
const ElementType &elementType,
1354
const ElementToken &elementToken,
1355
ModelGroupNode *parentModelGroupNode)
1356
: ContentTokenNodeBase(grove, elementType, parentModelGroupNode),
1357
elementToken_(elementToken) {}
1358
const ClassDef &classDef() const { return ClassDef::elementToken; }
1359
AccessResult getGi(GroveString &str) const;
1360
AccessResult getOccurIndicator(Node::OccurIndicator::Enum &) const;
1361
bool same(const BaseNode &) const;
1362
bool same2(const ElementTokenNode *) const;
1363
void accept(NodeVisitor &);
1364
unsigned long hash() const;
1365
const ElementToken &elementToken() const { return elementToken_; }
1367
const ElementToken &elementToken_;
1370
// CLASS DEF: PcdataTokenNode
1371
class PcdataTokenNode : public ContentTokenNodeBase {
1373
PcdataTokenNode(const GroveImpl *grove,
1374
const ElementType &elementType,
1375
const PcdataToken &pcdataToken,
1376
ModelGroupNode *parentModelGroupNode)
1377
: ContentTokenNodeBase(grove, elementType, parentModelGroupNode),
1378
pcdataToken_(pcdataToken) {}
1379
const ClassDef &classDef() const { return ClassDef::pcdataToken; }
1380
bool same(const BaseNode &) const;
1381
bool same2(const PcdataTokenNode *) const;
1382
void accept(NodeVisitor &);
1383
unsigned long hash() const;
1384
const PcdataToken &pcdataToken() const { return pcdataToken_; }
1386
const PcdataToken &pcdataToken_;
1389
// CLASS DEF: ModelGroupNode
1390
class ModelGroupNode : public ContentTokenNodeBase {
1392
ModelGroupNode(const GroveImpl *grove,
1393
const ElementType &elementType,
1394
const ModelGroup &modelGroup,
1395
ModelGroupNode *parentModelGroupNode = 0)
1396
: ContentTokenNodeBase(grove, elementType, parentModelGroupNode),
1397
modelGroup_(modelGroup) {}
1398
const ClassDef &classDef() const { return ClassDef::modelGroup; }
1399
AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const;
1400
AccessResult getConnector(Node::Connector::Enum &con) const;
1401
AccessResult getOccurIndicator(Node::OccurIndicator::Enum &occur) const;
1402
AccessResult getContentTokens(NodeListPtr &) const;
1403
bool same(const BaseNode &) const;
1404
bool same2(const ModelGroupNode *) const;
1405
void accept(NodeVisitor &);
1406
unsigned long hash() const;
1407
void makeNode(NodePtr &ptr, unsigned contentTokenIdx);
1408
const ModelGroup &modelGroup() const { return modelGroup_; }
1410
const ModelGroup &modelGroup_;
1413
// class DEF: AttributeDefNode
1414
class AttributeDefNode : public BaseNode, public virtual AttributeDefOrigin {
1416
AttributeDefNode(const GroveImpl *grove, size_t attIndex)
1417
: BaseNode(grove), AttributeDefOrigin(attIndex) {}
1418
const ClassDef &classDef() const { return ClassDef::attributeDef; }
1419
AccessResult getOrigin(NodePtr &ptr) const;
1420
AccessResult getName(GroveString &) const;
1421
AccessResult getDeclValueType(Node::DeclValueType::Enum &) const;
1422
AccessResult getDefaultValueType(Node::DefaultValueType::Enum &) const;
1423
AccessResult getTokens(GroveStringListPtr &) const;
1424
AccessResult getCurrentAttributeIndex(long &) const;
1425
void accept(NodeVisitor &visitor);
1426
bool same(const BaseNode &node) const;
1427
bool same2(const AttributeDefNode *node) const;
1428
unsigned long hash() const;
1432
// class DEF: ElementTypeAttributeDefNode
1433
class ElementTypeAttributeDefNode
1434
: public AttributeDefNode, public ElementTypeAttributeDefOrigin {
1436
ElementTypeAttributeDefNode(const GroveImpl *grove,
1437
const ElementType &elementType,
1438
size_t attributeDefIdx)
1439
: AttributeDefNode(grove, attributeDefIdx),
1440
ElementTypeAttributeDefOrigin(&elementType),
1441
AttributeDefOrigin(attributeDefIdx) {}
1442
AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
1443
name = ComponentName::idAttributeDefs;
1446
AccessResult getCurrentGroup(NodeListPtr &) const;
1447
AccessResult getLocation(Location &) const;
1448
AccessResult getDefaultValue(NodeListPtr &) const;
1451
// class DEF: NotationAttributeDefNode
1452
class NotationAttributeDefNode
1453
: public AttributeDefNode, public NotationAttributeDefOrigin {
1455
NotationAttributeDefNode(const GroveImpl *grove,
1456
const Notation ¬ation,
1457
size_t attributeDefIdx)
1458
: AttributeDefNode(grove, attributeDefIdx),
1459
NotationAttributeDefOrigin(¬ation),
1460
AttributeDefOrigin(attributeDefIdx) {};
1461
AccessResult getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const {
1462
name = ComponentName::idAttributeDefs;
1465
AccessResult getCurrentGroup(NodeListPtr &) const;
1466
AccessResult getLocation(Location &) const;
1467
//AccessResult getDefaultValue(NodeListPtr &) const;
1470
class BaseNodeList : public NodeList {
1472
BaseNodeList() : refCount_(0) { }
1473
virtual ~BaseNodeList() { }
1474
void addRef() { ++refCount_; }
1475
bool canReuse(NodeListPtr &ptr) const {
1476
const NodeList *tem = &*ptr;
1477
return tem == this && refCount_ == 1;
1480
ASSERT(refCount_ != 0);
1481
if (--refCount_ == 0) delete this;
1483
AccessResult first(NodePtr &) const { return accessNull; }
1484
AccessResult rest(NodeListPtr &ptr) const { return chunkRest(ptr); }
1485
AccessResult chunkRest(NodeListPtr &) const { return accessNull; }
1490
class SiblingNodeList : public BaseNodeList {
1492
SiblingNodeList(const NodePtr &first) : first_(first) { }
1493
AccessResult first(NodePtr &ptr) const {
1497
AccessResult rest(NodeListPtr &ptr) const {
1499
if (canReuse(ptr)) {
1500
ret = ((SiblingNodeList *)this)->first_.assignNextSibling();
1501
if (ret == accessOK)
1506
ret = first_->nextSibling(next);
1507
if (ret == accessOK) {
1508
ptr.assign(new SiblingNodeList(next));
1512
if (ret == accessNull) {
1513
ptr.assign(new BaseNodeList);
1518
AccessResult chunkRest(NodeListPtr &ptr) const {
1520
if (canReuse(ptr)) {
1521
ret = ((SiblingNodeList *)this)->first_.assignNextChunkSibling();
1522
if (ret == accessOK)
1527
ret = first_->nextChunkSibling(next);
1528
if (ret == accessOK) {
1529
ptr.assign(new SiblingNodeList(next));
1533
if (ret == accessNull) {
1534
ptr.assign(new BaseNodeList);
1539
AccessResult ref(unsigned long i, NodePtr &ptr) const {
1544
return first_->followSiblingRef(i - 1, ptr);
1547
NodePtr first_; // never null
1550
class BaseNamedNodeList : public NamedNodeList {
1552
BaseNamedNodeList(const GroveImpl *grove,
1553
const SubstTable<Char> *substTable)
1554
: grove_(grove), substTable_(substTable), refCount_(0) { }
1555
virtual ~BaseNamedNodeList() { }
1556
void addRef() { ++refCount_; }
1557
bool canReuse(NamedNodeListPtr &ptr) const {
1558
const NamedNodeList *tem = &*ptr;
1559
return tem == this && refCount_ == 1;
1562
ASSERT(refCount_ != 0);
1563
if (--refCount_ == 0) delete this;
1565
size_t normalize(Char *s, size_t n) const {
1567
for (size_t i = 0; i < n; i++)
1568
substTable_->subst(s[i]);
1572
const GroveImpl *grove() const { return grove_; }
1573
AccessResult namedNode(GroveString str, NodePtr &node) const {
1574
StringC tem(str.data(), str.size());
1575
normalize(&tem[0], tem.size());
1576
return namedNodeU(tem, node);
1578
virtual AccessResult namedNodeU(const StringC &, NodePtr &) const = 0;
1580
GroveImplPtr grove_;
1581
const SubstTable<Char> *substTable_;
1585
class AttributesNamedNodeList
1586
: public BaseNamedNodeList, public virtual AttributeOrigin {
1588
AttributesNamedNodeList(const GroveImpl *grove)
1589
: BaseNamedNodeList(grove, grove->generalSubstTable()) { }
1590
NodeListPtr nodeList() const;
1591
AccessResult namedNodeU(const StringC &, NodePtr &) const;
1592
Type type() const { return attributes; }
1595
class ElementAttributesNamedNodeList
1596
: public AttributesNamedNodeList, public ElementAttributeOrigin {
1598
ElementAttributesNamedNodeList(const GroveImpl *grove,
1599
const ElementChunk *chunk)
1600
: AttributesNamedNodeList(grove), ElementAttributeOrigin(chunk) { }
1603
class EntityAttributesNamedNodeList
1604
: public AttributesNamedNodeList, public EntityAttributeOrigin {
1606
EntityAttributesNamedNodeList(const GroveImpl *grove,
1607
const ExternalDataEntity *entity)
1608
: AttributesNamedNodeList(grove), EntityAttributeOrigin(entity) { }
1611
class ElementsNamedNodeList : public BaseNamedNodeList {
1613
ElementsNamedNodeList(const GroveImpl *grove)
1614
: BaseNamedNodeList(grove, grove->generalSubstTable()) { }
1615
NodeListPtr nodeList() const;
1616
AccessResult namedNodeU(const StringC &, NodePtr &) const;
1617
Type type() const { return elements; }
1620
class DocEntitiesNamedNodeList : public BaseNamedNodeList {
1622
DocEntitiesNamedNodeList(const GroveImpl *grove)
1623
: BaseNamedNodeList(grove, grove->entitySubstTable()) { }
1624
NodeListPtr nodeList() const;
1625
AccessResult namedNodeU(const StringC &, NodePtr &) const;
1626
Type type() const { return entities; }
1629
class DefaultedEntitiesNamedNodeList : public BaseNamedNodeList {
1631
DefaultedEntitiesNamedNodeList(const GroveImpl *grove)
1632
: BaseNamedNodeList(grove, grove->entitySubstTable()) { }
1633
NodeListPtr nodeList() const;
1634
AccessResult namedNodeU(const StringC &, NodePtr &) const;
1635
Type type() const { return entities; }
1638
class GeneralEntitiesNamedNodeList : public BaseNamedNodeList {
1640
GeneralEntitiesNamedNodeList(const GroveImpl *, const Dtd *);
1641
NodeListPtr nodeList() const;
1642
AccessResult namedNodeU(const StringC &, NodePtr &) const;
1643
Type type() const { return entities; }
1648
class ParameterEntitiesNamedNodeList : public BaseNamedNodeList {
1650
ParameterEntitiesNamedNodeList(const GroveImpl *, const Dtd *);
1651
NodeListPtr nodeList() const;
1652
AccessResult namedNodeU(const StringC &, NodePtr &) const;
1653
Type type() const { return entities; }
1658
class NotationsNamedNodeList : public BaseNamedNodeList {
1660
NotationsNamedNodeList(const GroveImpl *, const Dtd *);
1661
NodeListPtr nodeList() const;
1662
AccessResult namedNodeU(const StringC &, NodePtr &) const;
1663
Type type() const { return notations; }
1668
class DoctypesAndLinktypesNamedNodeList : public BaseNamedNodeList {
1670
DoctypesAndLinktypesNamedNodeList(const GroveImpl *);
1671
NodeListPtr nodeList() const;
1672
AccessResult namedNodeU(const StringC &, NodePtr &) const;
1673
Type type() const { return doctypesAndLinktypes; }
1676
class ElementsNodeList : public BaseNodeList {
1678
ElementsNodeList(const GroveImpl *grove,
1680
AccessResult first(NodePtr &) const;
1681
AccessResult chunkRest(NodeListPtr &) const;
1683
GroveImplPtr grove_;
1684
const Chunk *first_;
1687
class EntitiesNodeList : public BaseNodeList {
1689
EntitiesNodeList(const GroveImpl *grove,
1690
const Dtd::ConstEntityIter &iter);
1691
AccessResult first(NodePtr &) const;
1692
AccessResult chunkRest(NodeListPtr &) const;
1694
const GroveImpl *grove() const { return grove_; }
1696
GroveImplPtr grove_;
1697
Dtd::ConstEntityIter iter_;
1700
class DocEntitiesNodeList : public EntitiesNodeList {
1702
DocEntitiesNodeList(const GroveImpl *grove);
1703
AccessResult first(NodePtr &) const;
1704
AccessResult chunkRest(NodeListPtr &) const;
1707
class NotationsNodeList : public BaseNodeList {
1709
NotationsNodeList(const GroveImpl *grove,
1710
const Dtd::ConstNotationIter &iter);
1711
AccessResult first(NodePtr &) const;
1712
AccessResult chunkRest(NodeListPtr &) const;
1714
GroveImplPtr grove_;
1715
Dtd::ConstNotationIter iter_;
1718
// -- CLASS DEF: ElementTypesNodeList
1719
class ElementTypesNodeList : public BaseNodeList {
1721
ElementTypesNodeList( const GroveImpl *grove,
1722
const Dtd::ConstElementTypeIter &iter);
1723
AccessResult first(NodePtr &) const;
1724
AccessResult chunkRest(NodeListPtr &) const;
1726
GroveImplPtr grove_;
1727
Dtd::ConstElementTypeIter iter_;
1730
// -- CLASS DEF: ElementTypesNamedNodeList
1731
class ElementTypesNamedNodeList : public BaseNamedNodeList {
1733
ElementTypesNamedNodeList(const GroveImpl *, const Dtd *);
1734
NodeListPtr nodeList() const;
1735
AccessResult namedNodeU(const StringC &, NodePtr &) const;
1736
Type type() const { return elementTypes; }
1741
// -- CLASS DEF: ContentTokenNodeList
1742
class ContentTokenNodeList : public BaseNodeList {
1744
ContentTokenNodeList(const GroveImpl *grove,
1745
ModelGroupNode &modelGroupNode,
1746
unsigned firstTokenIdx = 0);
1747
AccessResult first(NodePtr &) const;
1748
AccessResult chunkRest(NodeListPtr &) const;
1749
unsigned firstTokenIdx() const { return firstTokenIdx_; }
1750
AccessResult next();
1752
GroveImplPtr grove_;
1753
ModelGroupNode &modelGroupNode_;
1754
unsigned firstTokenIdx_;
1757
// -- CLASS DEF: ModelGroupNodeList
1758
class ModelGroupNodeList : public BaseNodeList {
1760
ModelGroupNodeList(const GroveImpl *grove,
1761
const ModelGroup &modelGroupNode,
1762
size_t firstTokenIdx);
1763
AccessResult first(NodePtr &) const;
1764
AccessResult chunkRest(NodeListPtr &) const;
1766
GroveImplPtr grove_;
1767
ModelGroup &modelGroup_;
1768
size_t firstTokenIdx_;
1771
// -- CLASS DEF: AttributeDefsNodeList
1772
class AttributeDefsNodeList
1773
: public BaseNodeList, public virtual AttributeDefOrigin {
1775
AttributeDefsNodeList(const GroveImpl *grove,
1776
size_t firstAttIndex)
1777
: grove_(grove), AttributeDefOrigin(firstAttIndex) {}
1778
AccessResult first(NodePtr &) const;
1779
AccessResult chunkRest(NodeListPtr &) const;
1780
bool inList(size_t attIndex) const;
1782
GroveImplPtr grove_;
1785
// -- CLASS DEF: ElementTypeAttributeDefsNodeList
1786
class ElementTypeAttributeDefsNodeList
1787
: public AttributeDefsNodeList, public ElementTypeAttributeDefOrigin {
1789
ElementTypeAttributeDefsNodeList(const GroveImpl *grove,
1790
const ElementType &elementType,
1791
size_t firstAttIndex)
1792
: AttributeDefsNodeList(grove, firstAttIndex),
1793
ElementTypeAttributeDefOrigin(&elementType),
1794
AttributeDefOrigin(firstAttIndex) {}
1797
// -- CLASS DEF: NotationAttributeDefsNodeList
1798
class NotationAttributeDefsNodeList
1799
: public AttributeDefsNodeList, public NotationAttributeDefOrigin {
1801
NotationAttributeDefsNodeList(const GroveImpl *grove,
1802
const Notation ¬ation,
1803
size_t firstAttIndex)
1804
: AttributeDefsNodeList(grove, firstAttIndex),
1805
NotationAttributeDefOrigin(¬ation),
1806
AttributeDefOrigin(firstAttIndex) {}
1809
// -- CLASS DEF: AttributeDefsNamedNodeList
1810
class AttributeDefsNamedNodeList
1811
: public BaseNamedNodeList, public virtual AttributeDefOrigin {
1813
AttributeDefsNamedNodeList(const GroveImpl *grove)
1814
: BaseNamedNodeList(grove, grove->generalSubstTable()) { }
1815
NodeListPtr nodeList() const;
1816
AccessResult namedNodeU(const StringC &, NodePtr &) const;
1817
Type type() const { return attributeDefs; }
1820
// -- CLASS DEF: ElementTypeAttributeDefsNamedNodeList
1821
class ElementTypeAttributeDefsNamedNodeList
1822
: public AttributeDefsNamedNodeList, public ElementTypeAttributeDefOrigin {
1824
ElementTypeAttributeDefsNamedNodeList(const GroveImpl *grove,
1825
const ElementType &elementType)
1826
: AttributeDefsNamedNodeList(grove), ElementTypeAttributeDefOrigin(&elementType) { }
1829
// -- CLASS DEF: NotationAttributeDefsNamedNodeList
1830
class NotationAttributeDefsNamedNodeList
1831
: public AttributeDefsNamedNodeList, public NotationAttributeDefOrigin {
1833
NotationAttributeDefsNamedNodeList(const GroveImpl *grove,
1834
const Notation ¬ation)
1835
: AttributeDefsNamedNodeList(grove), NotationAttributeDefOrigin(¬ation) { }
1838
// -- CLASS DEF: ElementTypeCurrentGroupAttributeDefsNodeList
1839
// elementType_ is first list element, iter.next() represents rest
1840
class ElementTypeCurrentGroupAttributeDefsNodeList
1841
: public BaseNodeList {
1843
ElementTypeCurrentGroupAttributeDefsNodeList(const GroveImpl *grove,
1844
const Dtd::ConstElementTypeIter &iter,
1845
size_t currentGroupIndex);
1846
ElementTypeCurrentGroupAttributeDefsNodeList(const GroveImpl *grove,
1847
const Dtd::ConstElementTypeIter &iter,
1848
const ElementType *elementType,
1849
size_t firstAttIndex,
1850
size_t currentGroupIndex)
1851
: grove_(grove), iter_(iter), elementType_(elementType), attIndex_(firstAttIndex),
1852
currentGroupIndex_(currentGroupIndex) {}
1853
AccessResult first(NodePtr &) const;
1854
AccessResult chunkRest(NodeListPtr &) const;
1855
bool next(Dtd::ConstElementTypeIter &iter,
1856
const ElementType *&elementType,
1858
bool incrementFirst = true) const;
1859
bool next(bool incrementFirst = true) {
1860
return next(iter_, elementType_, attIndex_, incrementFirst); }
1862
GroveImplPtr grove_;
1863
Dtd::ConstElementTypeIter iter_;
1864
const ElementType *elementType_;
1865
size_t currentGroupIndex_;
1870
Boolean GroveImpl::waitForMoreNodes() const
1873
return moreNodesCondition_.wait();
1879
void GroveImpl::pulse()
1881
moreNodesCondition_.pulse();
1885
void GroveImpl::maybePulse()
1887
// Once we've had (2^n)*(2^10) events, only pulse every (2^n)th event.
1888
// Up to a limit of n == 8.
1889
// This reduces the overhead of pulsing to negligible levels on WinNT.
1890
if ((++nEvents_ & ~(~unsigned(0) << pulseStep_)) == 0) {
1892
if (pulseStep_ < 8 && nEvents_ > (1 << (pulseStep_ + 10)))
1898
void GroveImpl::appendSibling(Chunk *chunk)
1902
// Must set completeLimit_ before setting tailPtr_.
1903
completeLimit_ = pendingData_->after();
1904
*tailPtr_ = pendingData_;
1909
// Must set origin before advancing completeLimit_.
1910
chunk->origin = origin_;
1911
// Must advance completeLimit_ before setting tailPtr_.
1912
completeLimit_ = freePtr_;
1922
void GroveImpl::appendSibling(DataChunk *chunk)
1924
// Since we might extend this DataChunk, it's
1925
// not safe to set completeLimit_ to after this chunk yet.
1926
// This means we can't yet set tailPtr_.
1928
// Must set completeLimit_ before setting tailPtr_.
1929
completeLimit_ = pendingData_->after();
1931
*tailPtr_ = pendingData_;
1935
chunk->origin = origin_;
1936
pendingData_ = chunk;
1941
void GroveImpl::push(ElementChunk *chunk, Boolean hasId)
1945
// Must set completeLimit_ before setting tailPtr_.
1946
completeLimit_ = pendingData_->after();
1947
*tailPtr_ = pendingData_;
1952
chunk->elementIndex = nElements_++;
1953
chunk->origin = origin_;
1954
// Must set origin_ to chunk before advancing completeLimit_
1955
// otherwise thread would look at element and
1956
// maybeMoreSiblings() would return false.
1957
// Must advance completeLimit_ before setting tailPtr_,
1958
// otherwise tailPtr_ would be beyond completeLimit_.
1960
completeLimit_ = freePtr_;
1961
// Allow for the possibility of invalid documents with elements
1962
// after the document element.
1963
if ((const Chunk *)chunk->origin == root_ && root_->documentElement == 0)
1964
root_->documentElement = chunk;
1965
else if (tailPtr_) {
1970
Mutex::Lock lock(mutexPtr_);
1971
idTable_.insert(chunk);
1977
void GroveImpl::pop()
1980
// Must set completeLimit_ before setting tailPtr_.
1981
completeLimit_ = pendingData_->after();
1983
*tailPtr_ = pendingData_;
1988
tailPtr_ = &origin_->nextSibling;
1989
origin_ = origin_->origin;
1990
if ((const Chunk *)origin_ == root_)
1991
finishDocumentElement();
1996
Boolean GroveImpl::haveRootOrigin()
1998
return (const Chunk *)origin_ == root_;
2002
void GroveImpl::setDtd(const ConstPtr<Dtd> &dtd)
2005
hasDefaultEntity_ = !dtd_->defaultEntity().isNull();
2011
const ElementChunk *GroveImpl::lookupElement(const StringC &id) const
2013
Mutex::Lock lock(mutexPtr_);
2014
return idTable_.lookup(id);
2018
GroveImpl::ElementIter GroveImpl::elementIter() const
2021
return ElementIter(idTable_);
2025
Boolean GroveImpl::maybeMoreSiblings(const ParentChunk *chunk) const
2028
? chunk->nextSibling != 0
2030
|| &chunk->nextSibling == tailPtr_
2031
|| maybeMoreSiblings1(chunk)));
2035
void *GroveImpl::allocChunk(size_t n)
2037
nChunksSinceLocOrigin_++;
2045
return allocFinish(n);
2049
void GroveImpl::setLocOrigin(const ConstPtr<Origin> &locOrigin)
2051
if (locOrigin.pointer() != currentLocOrigin_
2052
|| nChunksSinceLocOrigin_ >= maxChunksWithoutLocOrigin)
2053
storeLocOrigin(locOrigin);
2057
void GroveImpl::appendMessage(MessageItem *item)
2059
*messageListTailP_ = item;
2060
messageListTailP_ = item->nextP();
2065
void ElementNode::add(GroveImpl &grove, const StartElementEvent &event)
2067
grove.setLocOrigin(event.location().origin());
2068
ElementChunk *chunk;
2069
const AttributeList &atts = event.attributes();
2071
if (atts.nSpec() == 0 && !atts.anyCurrent()) {
2072
void *mem = grove.allocChunk(sizeof(ElementChunk));
2073
if (event.included())
2074
chunk = new (mem) IncludedElementChunk;
2076
chunk = new (mem) ElementChunk;
2080
chunk = makeAttElementChunk(grove, event, hasId);
2081
chunk->type = event.elementType();
2082
chunk->locIndex = event.location().index();
2083
grove.push(chunk, hasId);
2086
// We duplicate ChunkNode::nextChunkSibling to take advantage
2087
// of Node reuse (via setNodePtrFirst(NodePtr &, const DataNode *).
2089
AccessResult DataNode::nextChunkSibling(NodePtr &ptr) const
2091
// The forwarding chunk has origin = 0, so it will stop
2092
// the iteration before after() can return 0.
2093
const Chunk *p = chunk_->after();
2094
while (p == grove()->completeLimit())
2095
if (!grove()->waitForMoreNodes())
2096
return accessTimeout;
2097
if (p->origin != chunk_->origin)
2099
return p->setNodePtrFirst(ptr, this);
2103
void DataNode::reuseFor(const DataChunk *chunk, size_t index)
2110
void DataNode::add(GroveImpl &grove, const DataEvent &event)
2112
size_t dataLen = event.dataLength();
2114
DataChunk *chunk = grove.pendingData();
2116
&& event.location().origin().pointer() == grove.currentLocOrigin()
2117
&& event.location().index() == chunk->locIndex + chunk->size
2118
&& grove.tryExtend(CharsChunk::allocSize(chunk->size + dataLen)
2119
- CharsChunk::allocSize(chunk->size))) {
2120
memcpy((Char *)(chunk + 1) + chunk->size,
2122
dataLen * sizeof(Char));
2123
chunk->size += dataLen;
2126
grove.setLocOrigin(event.location().origin());
2127
chunk = new (grove.allocChunk(CharsChunk::allocSize(dataLen))) DataChunk;
2128
chunk->size = dataLen;
2129
chunk->locIndex = event.location().index();
2130
memcpy(chunk + 1, event.data(), dataLen * sizeof(Char));
2131
grove.appendSibling(chunk);
2136
GroveBuilderMessageEventHandler::GroveBuilderMessageEventHandler(unsigned groveIndex,
2138
MessageFormatter *msgFmt)
2139
: mgr_(mgr), grove_(new GroveImpl(groveIndex)), msgFmt_(msgFmt)
2144
GroveBuilderMessageEventHandler::~GroveBuilderMessageEventHandler()
2146
grove_->setComplete();
2150
void GroveBuilderMessageEventHandler::makeInitialRoot(NodePtr &root)
2152
root.assign(new SgmlDocumentNode(grove_, grove_->root()));
2155
void GroveBuilderMessageEventHandler::message(MessageEvent *event)
2157
mgr_->dispatchMessage(event->message());
2158
const Message &msg = event->message();
2159
StrOutputCharStream os;
2160
msgFmt_->formatMessage(*msg.type, msg.args, os);
2162
os.extractString(tem);
2163
Node::Severity severity;
2164
switch (msg.type->severity()) {
2165
case MessageType::info:
2166
severity = Node::info;
2168
case MessageType::warning:
2169
severity = Node::warning;
2172
severity = Node::error;
2175
grove_->appendMessage(new MessageItem(severity, tem, msg.loc));
2176
if (!msg.auxLoc.origin().isNull()) {
2177
msgFmt_->formatMessage(msg.type->auxFragment(), msg.args, os);
2178
os.extractString(tem);
2179
grove_->appendMessage(new MessageItem(Node::info, tem, msg.auxLoc));
2181
ErrorCountEventHandler::message(event);
2184
void GroveBuilderMessageEventHandler::sgmlDecl(SgmlDeclEvent *event)
2186
grove_->setSd(event->sdPointer(), event->prologSyntaxPointer(), event->instanceSyntaxPointer());
2190
void GroveBuilderMessageEventHandler::setSd(const ConstPtr<Sd> &sd, const ConstPtr<Syntax> &prologSyntax, const ConstPtr<Syntax> &instanceSyntax)
2192
grove_->setSd(sd, prologSyntax, instanceSyntax);
2195
GroveBuilderEventHandler::GroveBuilderEventHandler(unsigned groveIndex,
2197
MessageFormatter *msgFmt)
2198
: GroveBuilderMessageEventHandler(groveIndex, mgr, msgFmt)
2202
void GroveBuilderEventHandler::appinfo(AppinfoEvent *event)
2204
const StringC *appinfo;
2205
if (event->literal(appinfo))
2206
grove_->setAppinfo(*appinfo);
2210
void GroveBuilderEventHandler::endProlog(EndPrologEvent *event)
2212
grove_->setDtd(event->dtdPointer());
2216
void GroveBuilderEventHandler::startElement(StartElementEvent *event)
2218
ElementNode::add(*grove_, *event);
2222
void GroveBuilderEventHandler::endElement(EndElementEvent *event)
2228
void GroveBuilderEventHandler::data(DataEvent *event)
2230
DataNode::add(*grove_, *event);
2234
void GroveBuilderEventHandler::sdataEntity(SdataEntityEvent *event)
2236
SdataNode::add(*grove_, *event);
2240
void GroveBuilderEventHandler::nonSgmlChar(NonSgmlCharEvent *event)
2242
NonSgmlNode::add(*grove_, *event);
2246
void GroveBuilderEventHandler::externalDataEntity(ExternalDataEntityEvent *event)
2248
ExternalDataNode::add(*grove_, *event);
2252
void GroveBuilderEventHandler::subdocEntity(SubdocEntityEvent *event)
2254
SubdocNode::add(*grove_, *event);
2258
void GroveBuilderEventHandler::pi(PiEvent *event)
2260
PiNode::add(*grove_, *event);
2264
void GroveBuilderEventHandler::entityDefaulted(EntityDefaultedEvent *event)
2266
grove_->addDefaultedEntity(event->entityPointer());
2270
ErrorCountEventHandler *GroveBuilder::make(unsigned index,
2272
MessageFormatter *msgFmt,
2276
GroveBuilderMessageEventHandler *eh;
2278
eh = new GroveBuilderMessageEventHandler(index, mgr, msgFmt);
2280
eh = new GroveBuilderEventHandler(index, mgr, msgFmt);
2281
eh->makeInitialRoot(root);
2285
ErrorCountEventHandler *GroveBuilder::make(unsigned index,
2287
MessageFormatter *msgFmt,
2289
const ConstPtr<Sd> &sd,
2290
const ConstPtr<Syntax> &prologSyntax,
2291
const ConstPtr<Syntax> &instanceSyntax,
2294
GroveBuilderMessageEventHandler *eh;
2296
eh = new GroveBuilderMessageEventHandler(index, mgr, msgFmt);
2298
eh = new GroveBuilderEventHandler(index, mgr, msgFmt);
2299
eh->makeInitialRoot(root);
2300
eh->setSd(sd, prologSyntax, instanceSyntax);
2304
bool GroveBuilder::setBlocking(bool b)
2306
bool prev = blockingAccess;
2311
GroveImpl::GroveImpl(unsigned groveIndex)
2312
: groveIndex_(groveIndex),
2314
impliedAttributeValue_(new ImpliedAttributeValue),
2319
blockTailPtr_(&blocks_),
2320
blockAllocSize_(initialBlockSize),
2321
nBlocksThisSizeAlloced_(0),
2329
currentLocOrigin_(0),
2330
completeLimitWithLocChunkAfter_(0),
2331
nChunksSinceLocOrigin_(0),
2333
messageListTailP_(&messageList_)
2335
root_ = new (allocChunk(sizeof(SgmlDocumentChunk))) SgmlDocumentChunk;
2337
root_->locIndex = 0;
2338
completeLimit_ = freePtr_;
2340
tailPtr_ = &root_->prolog;
2343
GroveImpl::~GroveImpl()
2346
BlockHeader *tem = blocks_;
2347
blocks_ = blocks_->next;
2348
::operator delete(tem);
2350
while (messageList_) {
2351
MessageItem *tem = messageList_;
2352
messageList_ = *messageList_->nextP();
2357
void GroveImpl::setAppinfo(const StringC &appinfo)
2363
Boolean GroveImpl::getAppinfo(const StringC *&appinfo) const
2365
if (!haveAppinfo_) {
2366
if (!complete_ && sd_.isNull())
2367
return 0; // not available yet
2371
appinfo = &appinfo_;
2375
void GroveImpl::setSd(const ConstPtr<Sd> &sd, const ConstPtr<Syntax> &prologSyntax, const ConstPtr<Syntax> &instanceSyntax)
2377
instanceSyntax_ = instanceSyntax;
2378
prologSyntax_ = prologSyntax;
2382
void GroveImpl::getSd(ConstPtr<Sd> &sd, ConstPtr<Syntax> &prologSyntax, ConstPtr<Syntax> &instanceSyntax) const
2384
instanceSyntax = instanceSyntax_;
2385
prologSyntax = prologSyntax_;
2389
void GroveImpl::finishProlog()
2396
void GroveImpl::finishDocumentElement()
2398
// Be robust in the case of erroneous documents.
2399
if (root_->epilog == 0) {
2401
tailPtr_ = &root_->epilog;
2405
void GroveImpl::addBarrier()
2408
(void) new (freePtr_) ForwardingChunk(0, 0);
2409
if (nFree_ <= sizeof(ForwardingChunk)) {
2414
nFree_ -= sizeof(ForwardingChunk);
2415
freePtr_ += sizeof(ForwardingChunk);
2420
void GroveImpl::setComplete()
2425
completeLimitWithLocChunkAfter_ = 0;
2426
if (pendingData_ && tailPtr_)
2427
*tailPtr_ = pendingData_;
2431
moreNodesCondition_.set();
2434
void GroveImpl::addDefaultedEntity(const ConstPtr<Entity> &entity)
2436
Mutex::Lock lock(mutexPtr_);
2437
// We need a table of ConstPtr<Entity> but we don't have one.
2438
defaultedEntityTable_.insert((Entity *)entity.pointer());
2441
const Entity *GroveImpl::lookupDefaultedEntity(const StringC &name) const
2443
Mutex::Lock lock(mutexPtr_);
2444
return defaultedEntityTable_.lookupTemp(name);
2447
Dtd::ConstEntityIter GroveImpl::defaultedEntityIter() const
2450
return Dtd::ConstEntityIter(defaultedEntityTable_);
2453
Boolean GroveImpl::maybeMoreSiblings1(const ParentChunk *chunk) const
2455
for (const ParentChunk *open = origin_; open; open = open->origin)
2458
// for multi-thread case
2459
return tailPtr_ == &chunk->nextSibling || chunk->nextSibling != 0;
2462
void *GroveImpl::allocFinish(size_t n)
2464
if (++nBlocksThisSizeAlloced_ >= maxBlocksPerSize) {
2465
blockAllocSize_ *= 2;
2466
nBlocksThisSizeAlloced_ = 0;
2468
size_t allocSize = n + (sizeof(ForwardingChunk) + sizeof(BlockHeader));
2469
if (allocSize < blockAllocSize_) {
2470
nFree_ = blockAllocSize_ - allocSize;
2471
allocSize = blockAllocSize_;
2475
*blockTailPtr_ = new (::operator new(allocSize)) BlockHeader;
2476
char *chunkStart = (char *)(*blockTailPtr_ + 1);
2477
blockTailPtr_ = &(*blockTailPtr_)->next;
2479
(void)new (freePtr_) ForwardingChunk((const Chunk *)chunkStart, origin_);
2480
freePtr_ = chunkStart + n;
2484
AccessResult ChunkNode::getLocation(Location &loc) const
2486
const Origin *origin = grove()->currentLocOrigin();
2487
for (const Chunk *p = chunk_->after(); p; p = p->after()) {
2488
if (p == grove()->completeLimitWithLocChunkAfter()) {
2489
while (!p->getLocOrigin(origin)) {
2495
if (p == grove()->completeLimit() || p->getLocOrigin(origin))
2500
loc = Location(new GroveImplProxyOrigin(grove(), origin), chunk_->locIndex);
2504
void GroveImpl::storeLocOrigin(const ConstPtr<Origin> &locOrigin)
2506
LocOriginChunk *chunk
2507
= new (allocChunk(sizeof(LocOriginChunk)))
2508
LocOriginChunk(currentLocOrigin_);
2509
chunk->origin = origin_;
2510
completeLimitWithLocChunkAfter_ = completeLimit_;
2511
nChunksSinceLocOrigin_ = 0;
2512
if (locOrigin.pointer() == currentLocOrigin_)
2514
if (currentLocOrigin_
2515
&& locOrigin == currentLocOrigin_->parent().origin()) {
2516
// Don't need to store it.
2517
currentLocOrigin_ = locOrigin.pointer();
2520
currentLocOrigin_ = locOrigin.pointer();
2521
if (locOrigin.isNull())
2523
origins_.push_back(locOrigin);
2526
AccessResult GroveImpl::proxifyLocation(const Location &loc, Location &ret) const
2528
if (loc.origin().isNull())
2530
ret = Location(new GroveImplProxyOrigin(this, loc.origin().pointer()),
2535
NodeListPtr AttributesNamedNodeList::nodeList() const
2537
const AttributeDefinitionList *defList = attDefList();
2538
if (!defList || defList->size() == 0)
2539
return new BaseNodeList;
2541
return new SiblingNodeList(makeAttributeAsgnNode(grove(), 0));
2545
AttributesNamedNodeList::namedNodeU(const StringC &str, NodePtr &ptr) const
2547
const AttributeDefinitionList *defList = attDefList();
2549
for (size_t i = 0; i < defList->size(); i++)
2550
if (defList->def(i)->name() == str) {
2551
ptr.assign(makeAttributeAsgnNode(grove(), i));
2558
void SgmlDocumentNode::accept(NodeVisitor &visitor)
2560
visitor.sgmlDocument(*this);
2563
AccessResult SgmlDocumentNode::getSgmlConstants(NodePtr &ptr) const
2565
ptr.assign(new SgmlConstantsNode(grove()));
2569
AccessResult SgmlDocumentNode::getApplicationInfo(GroveString &str) const
2571
const StringC *appinfo;
2572
while (!grove()->getAppinfo(appinfo))
2573
if (!grove()->waitForMoreNodes())
2574
return accessTimeout;
2577
setString(str, *appinfo);
2581
AccessResult SgmlDocumentNode::getDocumentElement(NodePtr &ptr) const
2583
while (chunk()->documentElement == 0) {
2584
if (grove()->complete()) {
2585
// Just in case another thread crept
2586
if (chunk()->documentElement)
2590
if (!grove()->waitForMoreNodes())
2591
return accessTimeout;
2593
return chunk()->documentElement->setNodePtrFirst(ptr, this);
2596
AccessResult SgmlDocumentNode::getProlog(NodeListPtr &ptr) const
2598
while (chunk()->prolog == 0) {
2599
if (chunk()->documentElement || grove()->complete())
2601
if (!grove()->waitForMoreNodes())
2602
return accessTimeout;
2604
if (chunk()->prolog == 0)
2605
ptr.assign(new BaseNodeList);
2608
chunk()->prolog->setNodePtrFirst(tem, this);
2609
ptr.assign(new SiblingNodeList(tem));
2614
AccessResult SgmlDocumentNode::getEpilog(NodeListPtr &ptr) const
2616
while (chunk()->epilog == 0) {
2617
if (grove()->complete())
2619
if (!grove()->waitForMoreNodes())
2620
return accessTimeout;
2622
if (chunk()->epilog == 0)
2623
ptr.assign(new BaseNodeList);
2626
chunk()->epilog->setNodePtrFirst(tem, this);
2627
ptr.assign(new SiblingNodeList(tem));
2632
AccessResult SgmlDocumentNode::getElements(NamedNodeListPtr &ptr) const
2634
while (!grove()->root()->documentElement) {
2635
if (grove()->complete()) {
2636
if (grove()->root()->documentElement)
2640
if (!grove()->waitForMoreNodes())
2641
return accessTimeout;
2643
if (!grove()->generalSubstTable())
2645
ptr.assign(new ElementsNamedNodeList(grove()));
2649
AccessResult SgmlDocumentNode::getEntities(NamedNodeListPtr &ptr) const
2651
while (!grove()->governingDtd()) {
2652
if (grove()->complete()) {
2653
if (grove()->governingDtd())
2657
if (!grove()->waitForMoreNodes())
2658
return accessTimeout;
2660
ptr.assign(new DocEntitiesNamedNodeList(grove()));
2664
AccessResult SgmlDocumentNode::getDefaultedEntities(NamedNodeListPtr &ptr) const
2666
while (!grove()->complete())
2667
if (!grove()->waitForMoreNodes())
2668
return accessTimeout;
2669
ptr.assign(new DefaultedEntitiesNamedNodeList(grove()));
2673
AccessResult SgmlDocumentNode::getGoverningDoctype(NodePtr &ptr) const
2675
while (!grove()->governingDtd()) {
2676
if (grove()->complete()) {
2677
if (grove()->governingDtd())
2681
if (!grove()->waitForMoreNodes())
2682
return accessTimeout;
2684
ptr.assign(new DocumentTypeNode(grove(), grove()->governingDtd()));
2688
AccessResult SgmlDocumentNode::getDoctypesAndLinktypes(NamedNodeListPtr &ptr) const
2690
while (!grove()->governingDtd()) {
2691
if (grove()->complete()) {
2692
if (grove()->governingDtd())
2696
if (!grove()->waitForMoreNodes())
2697
return accessTimeout;
2699
ptr.assign(new DoctypesAndLinktypesNamedNodeList(grove()));
2703
AccessResult SgmlDocumentNode::getMessages(NodeListPtr &ptr) const
2705
while (grove()->messageList() == 0) {
2706
if (grove()->complete())
2708
if (!grove()->waitForMoreNodes())
2709
return accessTimeout;
2711
if (grove()->messageList()) {
2712
NodePtr tem(new MessageNode(grove(), grove()->messageList()));
2713
ptr.assign(new SiblingNodeList(tem));
2716
ptr.assign(new BaseNodeList);
2720
AccessResult SgmlDocumentNode::getSd(ConstPtr<Sd> &sd,
2721
ConstPtr<Syntax> &prologSyntax,
2722
ConstPtr<Syntax> &instanceSyntax) const
2724
while (!grove()->complete()) {
2725
if (!grove()->waitForMoreNodes())
2726
return accessTimeout;
2728
grove()->getSd(sd, prologSyntax, instanceSyntax);
2729
if (!sd.isNull() && !prologSyntax.isNull() && !instanceSyntax.isNull())
2735
SgmlDocumentChunk::setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const
2737
ptr.assign(new SgmlDocumentNode(node->grove(), this));
2741
DocumentTypeNode::DocumentTypeNode(const GroveImpl *grove, const Dtd *dtd)
2742
: BaseNode(grove), dtd_(dtd)
2746
AccessResult DocumentTypeNode::nextChunkSibling(NodePtr &) const
2751
AccessResult DocumentTypeNode::getName(GroveString &str) const
2753
setString(str, dtd_->name());
2757
AccessResult DocumentTypeNode::getGoverning(bool &governing) const
2759
governing = dtd_->isBase();
2763
AccessResult DocumentTypeNode::getGeneralEntities(NamedNodeListPtr &ptr) const
2765
ptr.assign(new GeneralEntitiesNamedNodeList(grove(), dtd_));
2769
AccessResult DocumentTypeNode::getParameterEntities(NamedNodeListPtr &ptr) const
2771
ptr.assign(new ParameterEntitiesNamedNodeList(grove(), dtd_));
2775
AccessResult DocumentTypeNode::getNotations(NamedNodeListPtr &ptr) const
2777
ptr.assign(new NotationsNamedNodeList(grove(), dtd_));
2781
AccessResult DocumentTypeNode::getElementTypes(NamedNodeListPtr &ptr) const
2783
ptr.assign(new ElementTypesNamedNodeList(grove(), dtd_));
2787
AccessResult DocumentTypeNode::getDefaultEntity(NodePtr &ptr) const
2789
const Entity *entity = dtd_->defaultEntityTemp();
2792
ptr.assign(new DefaultEntityNode(grove(), entity));
2796
AccessResult DocumentTypeNode::getOrigin(NodePtr &ptr) const
2798
ptr.assign(new SgmlDocumentNode(grove(), grove()->root()));
2802
void DocumentTypeNode::accept(NodeVisitor &visitor)
2804
visitor.documentType(*this);
2807
bool DocumentTypeNode::same(const BaseNode &node) const
2809
return node.same2(this);
2812
bool DocumentTypeNode::same2(const DocumentTypeNode *node) const
2814
return dtd_ == node->dtd_;
2817
SgmlConstantsNode::SgmlConstantsNode(const GroveImpl *grove)
2822
AccessResult SgmlConstantsNode::getOrigin(NodePtr &ptr) const
2824
ptr.assign(new SgmlDocumentNode(grove(), grove()->root()));
2828
void SgmlConstantsNode::accept(NodeVisitor &visitor)
2830
visitor.sgmlConstants(*this);
2833
bool SgmlConstantsNode::same(const BaseNode &node) const
2835
return node.same2(this);
2838
bool SgmlConstantsNode::same2(const SgmlConstantsNode *) const
2843
MessageNode::MessageNode(const GroveImpl *grove, const MessageItem *item)
2844
: BaseNode(grove), item_(item)
2848
AccessResult MessageNode::getOrigin(NodePtr &ptr) const
2850
ptr.assign(new SgmlDocumentNode(grove(), grove()->root()));
2854
AccessResult MessageNode::nextChunkSibling(NodePtr &ptr) const
2856
while (!item_->next()) {
2857
if (grove()->complete()) {
2862
if (!grove()->waitForMoreNodes())
2863
return accessTimeout;
2865
const MessageItem *p = item_->next();
2868
ptr.assign(new MessageNode(grove(), p));
2872
AccessResult MessageNode::firstSibling(NodePtr &ptr) const
2874
ptr.assign(new MessageNode(grove(), grove()->messageList()));
2878
AccessResult MessageNode::siblingsIndex(unsigned long &n) const
2881
for (const MessageItem *p = grove()->messageList(); p != item_; p = p->next())
2886
void MessageNode::accept(NodeVisitor &visitor)
2888
visitor.message(*this);
2891
bool MessageNode::same(const BaseNode &node) const
2893
return node.same2(this);
2896
bool MessageNode::same2(const MessageNode *node) const
2898
return item_ == node->item_;
2901
AccessResult MessageNode::getLocation(Location &loc) const
2903
return grove()->proxifyLocation(item_->loc(), loc);
2906
AccessResult MessageNode::getText(GroveString &str) const
2908
setString(str, item_->text());
2912
AccessResult MessageNode::getSeverity(Severity &severity) const
2914
severity = item_->severity();
2918
AccessResult ElementNode::nextChunkSibling(NodePtr &ptr) const
2920
while (!chunk()->nextSibling) {
2921
if (!grove()->maybeMoreSiblings(chunk())) {
2922
// Allow for the possibility of invalid documents with elements in the epilog.
2923
if ((const Chunk *)chunk() == grove()->root()->documentElement)
2924
return accessNotInClass;
2928
if (!grove()->waitForMoreNodes())
2929
return accessTimeout;
2931
return chunk()->nextSibling->setNodePtrFirst(ptr, this);
2934
// This is a duplicate of ChunkNode::nextChunkAfter
2935
// to take advantage of overloaded setNodePtrFirst.
2937
AccessResult ElementNode::nextChunkAfter(NodePtr &nd) const
2939
const Chunk *p = chunk_->after();
2940
while (p == grove()->completeLimit())
2941
if (!grove()->waitForMoreNodes())
2942
return accessTimeout;
2943
return p->setNodePtrFirst(nd, this);
2946
AccessResult ElementChunk::getFollowing(const GroveImpl *grove,
2948
unsigned long &n) const
2950
while (!nextSibling) {
2951
if (!grove->maybeMoreSiblings(this)) {
2952
if ((const Chunk *)origin == grove->root())
2953
return accessNotInClass;
2957
if (!grove->waitForMoreNodes())
2958
return accessTimeout;
2965
AccessResult ElementNode::firstChild(NodePtr &ptr) const
2967
const Chunk *p = chunk()->after();
2968
while (p == grove()->completeLimit()) {
2969
if (!grove()->waitForMoreNodes())
2970
return accessTimeout;
2972
if ((const Chunk *)(p->origin) == chunk())
2973
return p->setNodePtrFirst(ptr, this);
2977
AccessResult ElementNode::attributeRef(unsigned long n, NodePtr &ptr) const
2979
const AttributeDefinitionList *defList = chunk()->attDefList();
2980
if (!defList || n >= defList->size())
2982
ptr.assign(new ElementAttributeAsgnNode(grove(), size_t(n), chunk()));
2986
AccessResult ElementNode::getAttributes(NamedNodeListPtr &ptr) const
2988
ptr.assign(new ElementAttributesNamedNodeList(grove(), chunk()));
2992
AccessResult ElementNode::getGi(GroveString &str) const
2994
setString(str, chunk()->type->name());
2998
bool ElementNode::hasGi(GroveString str) const
3000
const StringC &gi = chunk()->type->name();
3001
size_t len = gi.size();
3002
if (len != str.size())
3004
const SubstTable<Char> *subst = grove()->generalSubstTable();
3007
for (size_t i = 0; i < len; i++)
3008
if ((*subst)[str[i]] != gi[i])
3013
AccessResult ElementNode::getId(GroveString &str) const
3015
const StringC *id = chunk()->id();
3018
setString(str, *id);
3022
AccessResult ElementNode::elementIndex(unsigned long &i) const
3024
i = chunk()->elementIndex;
3028
AccessResult ElementNode::getElementType(NodePtr &ptr) const
3030
if (chunk()->elementType() == 0)
3032
ptr.assign(new ElementTypeNode(grove(), *(chunk()->elementType())));
3036
AccessResult ElementNode::getContent(NodeListPtr &ptr) const
3038
return children(ptr);
3041
AccessResult ElementNode::getMustOmitEndTag(bool &b) const
3043
b = chunk()->mustOmitEndTag();
3047
AccessResult ElementNode::getIncluded(bool &b) const
3049
b = chunk()->included();
3053
void ElementNode::accept(NodeVisitor &visitor)
3055
visitor.element(*this);
3059
ElementNode::makeAttElementChunk(GroveImpl &grove,
3060
const StartElementEvent &event,
3063
const AttributeList &atts = event.attributes();
3064
size_t nAtts = atts.size();
3065
while (nAtts > 0 && !atts.specified(nAtts - 1) && !atts.current(nAtts - 1))
3067
ElementChunk *chunk;
3069
= grove.allocChunk(sizeof(AttElementChunk) + nAtts * sizeof(AttributeValue *));
3070
if (event.included()) {
3071
// Workaround VC++ 4.1 bug.
3072
AttElementChunk *tem = new (mem) IncludedAttElementChunk(nAtts);
3076
chunk = new (mem) AttElementChunk(nAtts);
3077
const AttributeValue **values
3078
= (const AttributeValue **)(((AttElementChunk *)chunk) + 1);
3079
const AttributeDefinitionList *defList
3080
= event.elementType()->attributeDef().pointer();
3082
if (atts.idIndex(idIndex) && atts.specified(idIndex) && atts.value(idIndex))
3086
for (size_t i = 0; i < nAtts; i++) {
3087
if (atts.specified(i) || atts.current(i)) {
3088
grove.storeAttributeValue(atts.valuePointer(i));
3089
values[i] = atts.value(i);
3092
// If we stored a reference to the implied attribute value in the
3093
// Dtd then it would be safe just to use atts.value(i) here.
3094
// But that would mean we couldn't conveniently tell whether it
3095
// was specified or implied.
3096
values[i] = defList->def(i)->defaultValue(grove.impliedAttributeValue());
3102
const Chunk *AttElementChunk::after() const
3104
return (const Chunk *)((char *)(this + 1)
3105
+ (sizeof(const AttributeValue *) * nAtts));
3108
const AttributeValue *
3109
AttElementChunk::attributeValue(size_t attIndex, const GroveImpl &grove) const
3111
if (attIndex < nAtts)
3112
return ((const AttributeValue **)(this + 1))[attIndex];
3114
return ElementChunk::attributeValue(attIndex, grove);
3117
const StringC *AttElementChunk::id() const
3119
size_t i = ElementChunk::attDefList()->idIndex();
3120
if (i == size_t(-1) || i >= nAtts)
3122
const AttributeValue *av = ((const AttributeValue **)(this + 1))[i];
3125
const Text *t = av->text();
3128
return &t->string();
3131
Boolean AttElementChunk::mustOmitEndTag() const
3133
if (ElementChunk::mustOmitEndTag())
3135
const AttributeDefinitionList *adl = ElementChunk::attDefList();
3136
size_t nAtts = adl->size();
3137
const AttributeValue **atts = (const AttributeValue **)(this + 1);
3138
for (size_t i = 0; i < nAtts; i++)
3139
if (adl->def(i)->isConref() && atts[i] && atts[i]->text())
3144
const Chunk *ElementChunk::after() const
3149
const AttributeValue *
3150
ElementChunk::attributeValue(size_t attIndex, const GroveImpl &grove) const
3152
return attDefList()->def(attIndex)->defaultValue(grove.impliedAttributeValue());
3155
Boolean ElementChunk::mustOmitEndTag() const
3157
return type->definition()->declaredContent() == ElementDefinition::empty;
3160
Boolean IncludedElementChunk::included() const
3165
Boolean IncludedAttElementChunk::included() const
3170
Boolean ElementChunk::included() const
3176
ElementChunk::setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const
3178
ptr.assign(new ElementNode(node->grove(), this));
3183
ElementChunk::setNodePtrFirst(NodePtr &ptr, const ElementNode *node) const
3185
if (node->canReuse(ptr))
3186
((ElementNode *)node)->reuseFor(this);
3188
ptr.assign(new ElementNode(node->grove(), this));
3193
ElementChunk::setNodePtrFirst(NodePtr &ptr, const DataNode *node) const
3195
ptr.assign(new ElementNode(node->grove(), this));
3199
ElementAttributeOrigin::ElementAttributeOrigin(const ElementChunk *chunk)
3204
const AttributeDefinitionList *ElementAttributeOrigin::attDefList() const
3206
return chunk_->attDefList();
3210
const AttributeValue *
3211
ElementAttributeOrigin::attributeValue(size_t attIndex, const GroveImpl &grove) const
3213
return chunk_->attributeValue(attIndex, grove);
3218
ElementAttributeOrigin::setNodePtrAttributeOrigin(NodePtr &ptr,
3219
const BaseNode *node) const
3221
return chunk_->setNodePtrFirst(ptr, node);
3225
Node *ElementAttributeOrigin
3226
::makeCdataAttributeValueNode(const GroveImpl *grove,
3227
const AttributeValue *value,
3229
const TextIter &iter,
3230
size_t charIndex) const
3232
return new ElementCdataAttributeValueNode(grove, value, attIndex, iter,
3237
Node *ElementAttributeOrigin
3238
::makeAttributeValueTokenNode(const GroveImpl *grove,
3239
const TokenizedAttributeValue *value,
3241
size_t tokenIndex) const
3243
return new ElementAttributeValueTokenNode(grove, value, attIndex,
3244
tokenIndex, chunk_);
3247
Node *ElementAttributeOrigin
3248
::makeAttributeAsgnNode(const GroveImpl *grove,
3249
size_t attIndex) const
3251
return new ElementAttributeAsgnNode(grove, attIndex, chunk_);
3254
AccessResult ElementAttributeOrigin
3255
::makeAttributeDefNode(const GroveImpl *grove,
3257
size_t attributeDefIdx) const
3259
if (chunk_->elementType() == 0)
3261
ptr.assign(new ElementTypeAttributeDefNode(grove,
3262
*(chunk_->elementType()),
3267
Node *ElementAttributeOrigin::makeOriginNode(const GroveImpl *grove, size_t attIndex) const
3269
return makeAttributeAsgnNode(grove, attIndex);
3272
const void *ElementAttributeOrigin::attributeOriginId() const
3277
bool DataNode::same(const BaseNode &node) const
3279
return node.same2(this);
3282
bool DataNode::same2(const DataNode *node) const
3284
return chunk_ == node->chunk_ && index_ == node->index_;
3287
bool DataNode::chunkContains(const Node &node) const
3289
if (!sameGrove(node))
3291
return ((const BaseNode &)node).inChunk(this);
3294
bool DataNode::inChunk(const DataNode *node) const
3296
return chunk_ == node->chunk_ && index_ >= node->index_;
3299
AccessResult DataNode::charChunk(const SdataMapper &, GroveString &str) const
3301
str.assign(chunk()->data() + index_, chunk()->size - index_);
3305
void DataNode::accept(NodeVisitor &visitor)
3307
visitor.dataChar(*this);
3310
unsigned long DataNode::hash() const
3312
return secondHash(ChunkNode::hash() + index_);
3315
AccessResult DataNode::getNonSgml(unsigned long &) const
3320
AccessResult DataNode::nextSibling(NodePtr &ptr) const
3322
if (index_ + 1 < chunk()->size) {
3324
((DataNode *)this)->index_ += 1;
3326
ptr.assign(new DataNode(grove(), chunk(), index_ + 1));
3329
return DataNode::nextChunkSibling(ptr);
3332
AccessResult DataNode::nextChunkAfter(NodePtr &nd) const
3334
const Chunk *p = chunk_->after();
3335
while (p == grove()->completeLimit())
3336
if (!grove()->waitForMoreNodes())
3337
return accessTimeout;
3338
return p->setNodePtrFirst(nd, this);
3341
AccessResult DataNode::followSiblingRef(unsigned long i, NodePtr &ptr) const
3343
if (i < chunk()->size - index_ - 1) {
3345
((DataNode *)this)->index_ += 1 + size_t(i);
3347
ptr.assign(new DataNode(grove(), chunk(), index_ + size_t(i) + 1));
3350
return ChunkNode::followSiblingRef(i - (chunk()->size - index_ - 1), ptr);
3353
AccessResult DataNode::siblingsIndex(unsigned long &i) const
3355
AccessResult ret = ChunkNode::siblingsIndex(i);
3356
if (ret == accessOK)
3361
AccessResult DataNode::getLocation(Location &loc) const
3363
AccessResult ret = ChunkNode::getLocation(loc);
3364
if (ret == accessOK)
3369
AccessResult DataChunk::getFollowing(const GroveImpl *grove,
3371
unsigned long &i) const
3373
// We could call Chunk::getFollowing to do most of
3374
// the work, but that would cost us a couple of extra
3375
// virtual function calls.
3376
const Chunk *p = CharsChunk::after();
3377
while (p == grove->completeLimit())
3378
if (!grove->waitForMoreNodes())
3379
return accessTimeout;
3380
if (p->origin != origin)
3387
AccessResult DataChunk::setNodePtrFirst(NodePtr &ptr,
3388
const BaseNode *node) const
3390
ptr.assign(new DataNode(node->grove(), this, 0));
3394
// This just saves us a virtual function call in a common case
3395
AccessResult DataChunk::setNodePtrFirst(NodePtr &ptr,
3396
const ElementNode *node) const
3398
ptr.assign(new DataNode(node->grove(), this, 0));
3402
AccessResult DataChunk::setNodePtrFirst(NodePtr &ptr, const DataNode *node)
3405
if (node->canReuse(ptr))
3406
((DataNode *)node)->reuseFor(this, 0);
3408
ptr.assign(new DataNode(node->grove(), this, 0));
3412
AccessResult PiNode::getSystemData(GroveString &str) const
3414
str.assign(chunk()->data(), chunk()->size);
3418
void PiNode::add(GroveImpl &grove, const PiEvent &event)
3420
const Entity *entity = event.entity();
3422
PiEntityNode::add(grove, entity, event.location());
3424
grove.setLocOrigin(event.location().origin());
3425
size_t dataLen = event.dataLength();
3426
void *mem = grove.allocChunk(CharsChunk::allocSize(dataLen));
3428
if (grove.haveRootOrigin()) {
3429
if (grove.root()->documentElement)
3430
chunk = new (mem) EpilogPiChunk;
3432
chunk = new (mem) PrologPiChunk;
3435
chunk = new (mem) PiChunk;
3436
chunk->size = dataLen;
3437
chunk->locIndex = event.location().index();
3438
memcpy(chunk + 1, event.data(), dataLen * sizeof(Char));
3439
grove.appendSibling(chunk);
3443
AccessResult PiChunk::setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const
3445
ptr.assign(new PiNode(node->grove(), this));
3449
AccessResult PrologPiChunk::getFirstSibling(const GroveImpl *grove, const struct Chunk *&p) const
3451
p = grove->root()->prolog;
3455
AccessResult EpilogPiChunk::getFirstSibling(const GroveImpl *grove, const struct Chunk *&p) const
3457
p = grove->root()->epilog;
3461
AccessResult SdataNode::charChunk(const SdataMapper &mapper, GroveString &str) const
3463
const StringC &name = chunk()->entity->name();
3464
const StringC &text = chunk()->entity->asInternalEntity()->string();
3465
Char *cp = (Char *)&c_;
3466
if (mapper.sdataMap(GroveString(name.data(), name.size()), GroveString(text.data(), text.size()), *cp)) {
3474
AccessResult SdataNode::getSystemData(GroveString &str) const
3476
setString(str, chunk()->entity->asInternalEntity()->string());
3480
void SdataNode::add(GroveImpl &grove, const SdataEntityEvent &event)
3482
const Location &loc = event.location().origin()->parent();
3483
grove.setLocOrigin(loc.origin());
3484
SdataChunk *chunk = new (grove.allocChunk(sizeof(SdataChunk))) SdataChunk;
3485
chunk->entity = event.entity();
3486
chunk->locIndex = loc.index();
3487
grove.appendSibling(chunk);
3490
AccessResult SdataChunk::setNodePtrFirst(NodePtr &ptr, const BaseNode *node)
3493
ptr.assign(new SdataNode(node->grove(), this));
3497
AccessResult NonSgmlChunk::setNodePtrFirst(NodePtr &ptr, const BaseNode *node)
3500
ptr.assign(new NonSgmlNode(node->grove(), this));
3504
AccessResult NonSgmlNode::getNonSgml(unsigned long &n) const
3510
AccessResult NonSgmlNode::charChunk(const SdataMapper &, GroveString &) const
3515
void NonSgmlNode::add(GroveImpl &grove, const NonSgmlCharEvent &event)
3517
grove.setLocOrigin(event.location().origin());
3518
NonSgmlChunk *chunk = new (grove.allocChunk(sizeof(NonSgmlChunk))) NonSgmlChunk;
3519
chunk->c = event.character();
3520
chunk->locIndex = event.location().index();
3521
grove.appendSibling(chunk);
3524
void ExternalDataNode::add(GroveImpl &grove, const ExternalDataEntityEvent &event)
3526
grove.setLocOrigin(event.location().origin());
3527
ExternalDataChunk *chunk = new (grove.allocChunk(sizeof(ExternalDataChunk))) ExternalDataChunk;
3528
chunk->entity = event.entity();
3529
chunk->locIndex = event.location().index();
3530
grove.appendSibling(chunk);
3533
AccessResult ExternalDataChunk::setNodePtrFirst(NodePtr &ptr, const BaseNode *node)
3536
ptr.assign(new ExternalDataNode(node->grove(), this));
3540
void SubdocNode::add(GroveImpl &grove, const SubdocEntityEvent &event)
3542
grove.setLocOrigin(event.location().origin());
3543
SubdocChunk *chunk = new (grove.allocChunk(sizeof(SubdocChunk))) SubdocChunk;
3544
chunk->entity = event.entity();
3545
chunk->locIndex = event.location().index();
3546
grove.appendSibling(chunk);
3549
AccessResult SubdocChunk::setNodePtrFirst(NodePtr &ptr, const BaseNode *node)
3552
ptr.assign(new SubdocNode(node->grove(), this));
3556
AccessResult PiEntityNode::getSystemData(GroveString &str) const
3558
setString(str, chunk()->entity->asInternalEntity()->string());
3562
void PiEntityNode::add(GroveImpl &grove, const Entity *entity,
3563
const Location &loc)
3565
// FIXME use parent?
3566
grove.setLocOrigin(loc.origin());
3567
PiEntityChunk *chunk = new (grove.allocChunk(sizeof(PiEntityChunk))) PiEntityChunk;
3568
chunk->entity = entity;
3569
chunk->locIndex = loc.index();
3570
grove.appendSibling(chunk);
3573
AccessResult PiEntityChunk::setNodePtrFirst(NodePtr &ptr, const BaseNode *node)
3576
ptr.assign(new PiEntityNode(node->grove(), this));
3580
AccessResult EntityRefNode::getEntity(NodePtr &ptr) const
3582
ptr.assign(new EntityNode(grove(), chunk()->entity));
3586
AccessResult EntityRefNode::getEntityName(GroveString &str) const
3588
setString(str, chunk()->entity->name());
3592
AttributeAsgnNode::AttributeAsgnNode(const GroveImpl *grove,
3594
: BaseNode(grove), AttributeDefOrigin(attIndex)
3598
AccessResult ChunkNode::nextChunkSibling(NodePtr &ptr) const
3600
// The forwarding chunk has origin = 0, so it will stop
3601
// the iteration before after() can return 0.
3602
const Chunk *p = chunk_->after();
3603
while (p == grove()->completeLimit())
3604
if (!grove()->waitForMoreNodes())
3605
return accessTimeout;
3606
if (p->origin != chunk_->origin)
3608
return p->setNodePtrFirst(ptr, this);
3611
AccessResult ChunkNode::nextChunkAfter(NodePtr &nd) const
3613
const Chunk *p = chunk_->after();
3614
while (p == grove()->completeLimit())
3615
if (!grove()->waitForMoreNodes())
3616
return accessTimeout;
3617
return p->setNodePtrFirst(nd, this);
3620
AccessResult ChunkNode::firstSibling(NodePtr &ptr) const
3623
AccessResult ret = chunk_->getFirstSibling(grove(), first);
3624
if (ret != accessOK)
3626
return first->setNodePtrFirst(ptr, this);
3629
AccessResult ChunkNode::siblingsIndex(unsigned long &i) const
3632
AccessResult ret = chunk_->getFirstSibling(grove(), p);
3633
if (ret != accessOK)
3636
while (p != chunk_) {
3638
if (p->getFollowing(grove(), p, tem) != accessOK)
3645
AccessResult ChunkNode::followSiblingRef(unsigned long i, NodePtr &ptr) const
3648
unsigned long count;
3649
AccessResult ret = chunk()->getFollowing(grove(), p, count);
3650
if (ret != accessOK)
3653
const Chunk *lastP = p;
3654
ret = p->getFollowing(grove(), p, count);
3655
if (ret == accessOK && count <= i)
3657
else if (ret == accessOK || ret == accessNull) {
3658
lastP->setNodePtrFirst(ptr, this);
3659
return ptr->followSiblingRef(i - 1, ptr);
3664
return p->setNodePtrFirst(ptr, this);
3667
AccessResult AttributeAsgnNode::getOrigin(NodePtr &ptr) const
3669
return setNodePtrAttributeOrigin(ptr, this);
3672
AccessResult AttributeAsgnNode::getName(GroveString &str) const
3674
setString(str, attDefList()->def(attIndex_)->name());
3678
AccessResult AttributeAsgnNode::getImplied(bool &implied) const
3680
const AttributeValue *value = attributeValue(attIndex_, *grove());
3681
implied = (value != 0 && value->text() == 0);
3685
AccessResult AttributeAsgnNode::getValue(NodeListPtr &ptr) const
3687
return children(ptr);
3690
AccessResult AttributeAsgnNode::nextChunkSibling(NodePtr &ptr) const
3692
return followSiblingRef(0, ptr);
3695
AccessResult AttributeAsgnNode::followSiblingRef(unsigned long i, NodePtr &ptr) const
3697
// Do it like this to avoid overflow.
3698
if (i >= attDefList()->size() - attIndex_ - 1)
3701
((AttributeAsgnNode *)this)->attIndex_ += size_t(i) + 1;
3703
ptr.assign(makeAttributeAsgnNode(grove(), attIndex_ + 1 + size_t(i)));
3707
AccessResult AttributeAsgnNode::firstSibling(NodePtr &ptr) const
3710
((AttributeAsgnNode *)this)->attIndex_ = 0;
3712
ptr.assign(makeAttributeAsgnNode(grove(), 0));
3716
AccessResult AttributeAsgnNode::siblingsIndex(unsigned long &i) const
3722
void AttributeAsgnNode::accept(NodeVisitor &visitor)
3724
visitor.attributeAssignment(*this);
3727
AccessResult AttributeAsgnNode::firstChild(NodePtr &ptr) const
3729
const AttributeValue *value = attributeValue(attIndex_, *grove());
3730
return makeAttributeValueNode(grove(), ptr, value);
3733
AccessResult AttributeAsgnNode::children(NodeListPtr &ptr) const
3735
const AttributeValue *value = attributeValue(attIndex_, *grove());
3736
return makeAttributeValueNodeList(grove(), ptr, value);
3739
AccessResult AttributeAsgnNode::getTokenSep(Char &ch) const
3741
const AttributeValue *value = attributeValue(attIndex_, *grove());
3746
if (value->info(text, str) != AttributeValue::tokenized)
3748
const TokenizedAttributeValue *tValue =
3749
(const TokenizedAttributeValue *)value;
3750
if (tValue->nTokens() <= 1)
3754
tValue->token(0, ptr, len);
3755
// the character following the token is a space
3760
AccessResult AttributeAsgnNode::tokens(GroveString &s) const
3762
const AttributeValue *value = attributeValue(attIndex_, *grove());
3767
if (value->info(text, str) != AttributeValue::tokenized)
3773
AccessResult AttributeAsgnNode::getAttributeDef(NodePtr &ptr) const
3775
return makeAttributeDefNode(grove(), ptr, attIndex_);
3778
bool AttributeAsgnNode::same(const BaseNode &node) const
3780
return node.same2(this);
3783
bool AttributeAsgnNode::same2(const AttributeAsgnNode *node)
3786
return (attributeOriginId() == node->attributeOriginId()
3787
&& attIndex_ == node->attIndex_);
3790
unsigned long AttributeAsgnNode::hash() const
3792
unsigned long n = (unsigned long)attributeOriginId();
3793
return secondHash(n + attIndex_);
3796
ElementAttributeAsgnNode
3797
::ElementAttributeAsgnNode(const GroveImpl *grove, size_t attIndex,
3798
const ElementChunk *chunk)
3799
: AttributeAsgnNode(grove, attIndex),
3800
ElementAttributeOrigin(chunk),
3801
AttributeDefOrigin(attIndex)
3805
EntityAttributeAsgnNode
3806
::EntityAttributeAsgnNode(const GroveImpl *grove, size_t attIndex,
3807
const ExternalDataEntity *entity)
3808
: AttributeAsgnNode(grove, attIndex),
3809
EntityAttributeOrigin(entity),
3810
AttributeDefOrigin(attIndex)
3814
CdataAttributeValueNode
3815
::CdataAttributeValueNode(const GroveImpl *grove,
3816
const AttributeValue *value,
3818
const TextIter &iter,
3821
AttributeDefOrigin(attIndex),
3824
charIndex_(charIndex)
3828
bool CdataAttributeValueNode::skipBoring(TextIter &iter)
3830
while (iter.valid()) {
3831
switch (iter.type()) {
3832
case TextItem::data:
3833
case TextItem::cdata:
3834
case TextItem::sdata:
3850
AccessResult CdataAttributeValueNode::getParent(NodePtr &ptr) const
3852
ptr.assign(makeOriginNode(grove(), attIndex_));
3856
AccessResult CdataAttributeValueNode::charChunk(const SdataMapper &mapper, GroveString &str) const
3858
if (iter_.type() == TextItem::sdata) {
3859
const Entity *entity = iter_.location().origin()->asEntityOrigin()->entity();
3860
const StringC &name = entity->name();
3861
const StringC &text = entity->asInternalEntity()->string();
3862
Char *cp = (Char *)&c_;
3863
if (mapper.sdataMap(GroveString(name.data(), name.size()), GroveString(text.data(), text.size()), *cp)) {
3871
const Char *s = iter_.chars(len);
3872
str.assign(s + charIndex_, len - charIndex_);
3876
AccessResult CdataAttributeValueNode::siblingsIndex(unsigned long &n) const
3878
TextIter copy(iter_);
3880
const Char *iterChars = iter_.chars(tem);
3884
while (copy.chars(tem) != iterChars) {
3885
if (copy.type() == TextItem::sdata)
3896
AccessResult CdataAttributeValueNode::getEntity(NodePtr &ptr) const
3898
if (iter_.type() != TextItem::sdata)
3899
return accessNotInClass;
3900
const Entity *entity
3901
= iter_.location().origin()->asEntityOrigin()->entity();
3902
ptr.assign(new EntityNode(grove(), entity));
3906
AccessResult CdataAttributeValueNode::getEntityName(GroveString &str) const
3908
if (iter_.type() != TextItem::sdata)
3909
return accessNotInClass;
3910
const Entity *entity
3911
= iter_.location().origin()->asEntityOrigin()->entity();
3912
setString(str, entity->name());
3916
AccessResult CdataAttributeValueNode::getSystemData(GroveString &str) const
3918
if (iter_.type() != TextItem::sdata)
3919
return accessNotInClass;
3921
const Char *ptr = iter_.chars(len);
3922
str.assign(ptr, len);
3926
AccessResult CdataAttributeValueNode::firstSibling(NodePtr &ptr) const
3928
TextIter copy(iter_);
3931
if (canReuse(ptr)) {
3932
CdataAttributeValueNode *node = (CdataAttributeValueNode *)this;
3934
node->charIndex_ = 0;
3937
ptr.assign(makeCdataAttributeValueNode(grove(), value_, attIndex_, copy));
3941
AccessResult CdataAttributeValueNode::nextChunkSibling(NodePtr &ptr) const
3943
TextIter copy(iter_);
3945
if (!skipBoring(copy))
3947
if (canReuse(ptr)) {
3948
CdataAttributeValueNode *node = (CdataAttributeValueNode *)this;
3950
node->charIndex_ = 0;
3953
ptr.assign(makeCdataAttributeValueNode(grove(), value_, attIndex_, copy));
3957
AccessResult CdataAttributeValueNode::nextSibling(NodePtr &ptr) const
3959
if (iter_.type() != TextItem::sdata) {
3961
iter_.chars(length);
3962
if (charIndex_ + 1 < length) {
3964
((CdataAttributeValueNode *)this)->charIndex_ += 1;
3966
ptr.assign(makeCdataAttributeValueNode(grove(), value_,
3972
return CdataAttributeValueNode::nextChunkSibling(ptr);
3975
AccessResult CdataAttributeValueNode::getLocation(Location &loc) const
3977
if (iter_.type() == TextItem::sdata)
3978
return grove()->proxifyLocation(iter_.location().origin()->parent(), loc);
3980
return grove()->proxifyLocation(iter_.location(), loc);
3983
void CdataAttributeValueNode::accept(NodeVisitor &visitor)
3985
if (iter_.type() == TextItem::sdata)
3986
visitor.sdata(*this);
3988
visitor.dataChar(*this);
3991
unsigned long CdataAttributeValueNode::hash() const
3994
CdataAttributeValueNode::siblingsIndex(n);
3995
return secondHash(secondHash((unsigned long)attributeOriginId() + attIndex_) + n);
3998
const ClassDef &CdataAttributeValueNode::classDef() const
4000
if (iter_.type() == TextItem::sdata)
4001
return ClassDef::sdata;
4003
return ClassDef::dataChar;
4006
bool CdataAttributeValueNode::same(const BaseNode &node) const
4008
return node.same2(this);
4011
bool CdataAttributeValueNode::same2(const CdataAttributeValueNode *node)
4015
return (attributeOriginId() == node->attributeOriginId()
4016
&& attIndex_ == node->attIndex_
4017
&& charIndex_ == node->charIndex_
4018
&& iter_.chars(tem) == node->iter_.chars(tem));
4021
bool CdataAttributeValueNode::chunkContains(const Node &node) const
4023
if (!sameGrove(node))
4025
return ((const BaseNode &)node).inChunk(this);
4028
bool CdataAttributeValueNode::inChunk(const CdataAttributeValueNode *node) const
4031
return (attributeOriginId() == node->attributeOriginId()
4032
&& attIndex_ == node->attIndex_
4033
&& iter_.chars(tem) == node->iter_.chars(tem)
4034
&& charIndex_ >= node->charIndex_);
4037
ElementCdataAttributeValueNode
4038
::ElementCdataAttributeValueNode(const GroveImpl *grove,
4039
const AttributeValue *value,
4041
const TextIter &iter,
4043
const ElementChunk *chunk)
4044
: CdataAttributeValueNode(grove, value, attIndex, iter, charIndex),
4045
ElementAttributeOrigin(chunk), AttributeDefOrigin(attIndex)
4049
EntityCdataAttributeValueNode
4050
::EntityCdataAttributeValueNode(const GroveImpl *grove,
4051
const AttributeValue *value,
4053
const TextIter &iter,
4055
const ExternalDataEntity *entity)
4056
: CdataAttributeValueNode(grove, value, attIndex, iter, charIndex),
4057
EntityAttributeOrigin(entity), AttributeDefOrigin(attIndex)
4061
ElementTypeCdataAttributeValueNode
4062
::ElementTypeCdataAttributeValueNode(const GroveImpl *grove,
4063
const AttributeValue *value,
4065
const TextIter &iter,
4067
const ElementType *elementType)
4068
: CdataAttributeValueNode(grove, value, attIndex, iter, charIndex),
4069
ElementTypeAttributeDefOrigin(elementType), AttributeDefOrigin(attIndex)
4073
NotationCdataAttributeValueNode
4074
::NotationCdataAttributeValueNode(const GroveImpl *grove,
4075
const AttributeValue *value,
4077
const TextIter &iter,
4079
const Notation *notation)
4080
: CdataAttributeValueNode(grove, value, attIndex, iter, charIndex),
4081
NotationAttributeDefOrigin(notation), AttributeDefOrigin(attIndex)
4085
AttributeValueTokenNode
4086
::AttributeValueTokenNode(const GroveImpl *grove,
4087
const TokenizedAttributeValue *value,
4088
size_t attIndex, size_t tokenIndex)
4090
AttributeDefOrigin(attIndex),
4092
tokenIndex_(tokenIndex)
4096
AccessResult AttributeValueTokenNode::getParent(NodePtr &ptr) const
4098
ptr.assign(makeOriginNode(grove(), attIndex_));
4102
AccessResult AttributeValueTokenNode::nextChunkSibling(NodePtr &ptr) const
4104
return followSiblingRef(0, ptr);
4107
AccessResult AttributeValueTokenNode::followSiblingRef(unsigned long i, NodePtr &ptr) const
4109
// Do it like this to avoid possibility of overflow
4110
if (i >= value_->nTokens() - tokenIndex_ - 1)
4112
if (canReuse(ptr)) {
4113
AttributeValueTokenNode *node = (AttributeValueTokenNode *)this;
4114
node->tokenIndex_ += size_t(i) + 1;
4117
ptr.assign(makeAttributeValueTokenNode(grove(), value_, attIndex_,
4118
tokenIndex_ + size_t(i) + 1));
4122
AccessResult AttributeValueTokenNode::firstSibling(NodePtr &ptr) const
4125
((AttributeValueTokenNode *)this)->tokenIndex_ = 0;
4127
ptr.assign(makeAttributeValueTokenNode(grove(), value_, attIndex_, 0));
4131
AccessResult AttributeValueTokenNode::siblingsIndex(unsigned long &i) const
4137
AccessResult AttributeValueTokenNode::getToken(GroveString &str) const
4141
value_->token(tokenIndex_, ptr, len);
4142
str.assign(ptr, len);
4146
AccessResult AttributeValueTokenNode::getEntity(NodePtr &ptr) const
4148
if (!attDefList()->def(attIndex_)->isEntity())
4150
StringC token(value_->token(tokenIndex_));
4151
const Entity *entity = grove()->governingDtd()->lookupEntityTemp(0, token);
4153
entity = grove()->lookupDefaultedEntity(token);
4157
ptr.assign(new EntityNode(grove(), entity));
4161
AccessResult AttributeValueTokenNode::getNotation(NodePtr &ptr) const
4163
if (!attDefList()->def(attIndex_)->isNotation())
4165
StringC token(value_->token(tokenIndex_));
4166
const Notation *notation = grove()->governingDtd()->lookupNotationTemp(token);
4169
ptr.assign(new NotationNode(grove(), notation));
4173
AccessResult AttributeValueTokenNode::getReferent(NodePtr &ptr) const
4175
if (!attDefList()->def(attIndex_)->isIdref())
4177
StringC token(value_->token(tokenIndex_));
4179
Boolean complete = grove()->complete();
4180
const ElementChunk *element = grove()->lookupElement(token);
4182
ptr.assign(new ElementNode(grove(), element));
4187
if (!grove()->waitForMoreNodes())
4188
return accessTimeout;
4193
void AttributeValueTokenNode::accept(NodeVisitor &visitor)
4195
visitor.attributeValueToken(*this);
4198
unsigned long AttributeValueTokenNode::hash() const
4200
return secondHash(secondHash((unsigned long)attributeOriginId() + attIndex_) + tokenIndex_);
4203
bool AttributeValueTokenNode::same(const BaseNode &node) const
4205
return node.same2(this);
4208
bool AttributeValueTokenNode::same2(const AttributeValueTokenNode *node) const
4210
return (attributeOriginId() == node->attributeOriginId()
4211
&& attIndex_ == node->attIndex_
4212
&& tokenIndex_ == node->tokenIndex_);
4215
AccessResult AttributeValueTokenNode::getLocation(Location &loc) const
4217
const ConstPtr<Origin> *originP;
4219
if (!value_->tokenLocation(tokenIndex_, originP, index)
4220
&& originP->pointer()) {
4221
loc = Location(new GroveImplProxyOrigin(grove(), originP->pointer()), index);
4227
ElementAttributeValueTokenNode
4228
::ElementAttributeValueTokenNode(const GroveImpl *grove,
4229
const TokenizedAttributeValue *value,
4232
const ElementChunk *chunk)
4233
: AttributeValueTokenNode(grove, value, attIndex, tokenIndex),
4234
ElementAttributeOrigin(chunk), AttributeDefOrigin(attIndex)
4238
EntityAttributeValueTokenNode
4239
::EntityAttributeValueTokenNode(const GroveImpl *grove,
4240
const TokenizedAttributeValue *value,
4243
const ExternalDataEntity *entity)
4244
: AttributeValueTokenNode(grove, value, attIndex, tokenIndex),
4245
EntityAttributeOrigin(entity), AttributeDefOrigin(attIndex)
4249
ElementTypeAttributeValueTokenNode
4250
::ElementTypeAttributeValueTokenNode(const GroveImpl *grove,
4251
const TokenizedAttributeValue *value,
4254
const ElementType *elementType)
4255
: AttributeValueTokenNode(grove, value, attIndex, tokenIndex),
4256
ElementTypeAttributeDefOrigin(elementType), AttributeDefOrigin(attIndex)
4260
NotationAttributeValueTokenNode
4261
::NotationAttributeValueTokenNode(const GroveImpl *grove,
4262
const TokenizedAttributeValue *value,
4265
const Notation *notation)
4266
: AttributeValueTokenNode(grove, value, attIndex, tokenIndex),
4267
NotationAttributeDefOrigin(notation), AttributeDefOrigin(attIndex)
4271
EntityNode::EntityNode(const GroveImpl *grove, const Entity *entity)
4272
: EntityNodeBase(grove, entity)
4276
DefaultEntityNode::DefaultEntityNode(const GroveImpl *grove, const Entity *entity)
4277
: EntityNodeBase(grove, entity)
4281
AccessResult EntityNode::getOrigin(NodePtr &ptr) const
4283
if (entity_->defaulted() && grove()->lookupDefaultedEntity(entity_->name()))
4284
ptr.assign(new SgmlDocumentNode(grove(), grove()->root()));
4286
ptr.assign(new DocumentTypeNode(grove(), grove()->governingDtd()));
4290
AccessResult DefaultEntityNode::getOrigin(NodePtr &ptr) const
4292
ptr.assign(new DocumentTypeNode(grove(), grove()->governingDtd()));
4296
AccessResult EntityNode::getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const
4298
if (entity_->defaulted() && grove()->lookupDefaultedEntity(entity_->name()))
4299
name = ComponentName::idDefaultedEntities;
4301
name = ComponentName::idGeneralEntities;
4305
AccessResult DefaultEntityNode::getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const
4307
name = ComponentName::idDefaultEntity;
4311
AccessResult EntityNodeBase::getName(GroveString &str) const
4313
setString(str, entity_->name());
4317
AccessResult EntityNodeBase::getExternalId(NodePtr &ptr) const
4319
const ExternalEntity *x = entity_->asExternalEntity();
4322
ptr.assign(new EntityExternalIdNode(grove(), x));
4326
AccessResult EntityNodeBase::getNotation(NodePtr &ptr) const
4328
const ExternalDataEntity *x = entity_->asExternalDataEntity();
4329
if (!x || !x->notation())
4331
ptr.assign(new NotationNode(grove(), x->notation()));
4335
AccessResult EntityNodeBase::getNotationName(GroveString &str) const
4337
const ExternalDataEntity *x = entity_->asExternalDataEntity();
4338
if (!x || !x->notation())
4340
setString(str, x->notation()->name());
4344
AccessResult EntityNodeBase::getText(GroveString &str) const
4346
const InternalEntity *i = entity_->asInternalEntity();
4349
setString(str, i->string());
4353
AccessResult EntityNodeBase::getEntityType(Node::EntityType::Enum &entityType) const
4355
switch (entity_->dataType()) {
4356
case EntityDecl::sgmlText:
4357
entityType = EntityType::text;
4359
case EntityDecl::pi:
4360
entityType = EntityType::pi;
4362
case EntityDecl::cdata:
4363
entityType = EntityType::cdata;
4365
case EntityDecl::sdata:
4366
entityType = EntityType::sdata;
4368
case EntityDecl::ndata:
4369
entityType = EntityType::ndata;
4371
case EntityDecl::subdoc:
4372
entityType = EntityType::subdocument;
4380
AccessResult EntityNode::getDefaulted(bool &dflted) const
4382
dflted = entity_->defaulted();
4386
AccessResult EntityNodeBase::getAttributes(NamedNodeListPtr &ptr) const
4388
const ExternalDataEntity *x = entity_->asExternalDataEntity();
4391
ptr.assign(new EntityAttributesNamedNodeList(grove(), x));
4395
AccessResult EntityNodeBase::attributeRef(unsigned long i, NodePtr &ptr) const
4397
const ExternalDataEntity *x = entity_->asExternalDataEntity();
4398
if (!x || i >= x->attributes().size())
4400
ptr.assign(new EntityAttributeAsgnNode(grove(), size_t(i), x));
4404
AccessResult EntityNodeBase::getLocation(Location &loc) const
4406
return grove()->proxifyLocation(entity_->defLocation(), loc);
4409
bool EntityNode::same(const BaseNode &node) const
4411
return node.same2(this);
4414
bool DefaultEntityNode::same(const BaseNode &node) const
4416
return node.same2(this);
4419
bool EntityNode::same2(const EntityNode *node) const
4421
return entity_ == node->entity_;
4424
bool DefaultEntityNode::same2(const DefaultEntityNode *node) const
4426
return entity_ == node->entity_;
4429
void EntityNode::accept(NodeVisitor &visitor)
4431
visitor.entity(*this);
4434
void DefaultEntityNode::accept(NodeVisitor &visitor)
4436
visitor.defaultEntity(*this);
4439
unsigned long EntityNodeBase::hash() const
4441
return (unsigned long)entity_;
4444
EntityAttributeOrigin
4445
::EntityAttributeOrigin(const ExternalDataEntity *entity)
4450
const AttributeDefinitionList *
4451
EntityAttributeOrigin::attDefList() const
4453
return entity_->notation()->attributeDefTemp();
4457
const AttributeValue *
4458
EntityAttributeOrigin::attributeValue(size_t attIndex, const GroveImpl &) const
4460
return entity_->attributes().value(attIndex);
4464
EntityAttributeOrigin::setNodePtrAttributeOrigin(NodePtr &ptr,
4465
const BaseNode *node) const
4467
ptr.assign(new EntityNode(node->grove(), entity_));
4471
Node *EntityAttributeOrigin
4472
::makeCdataAttributeValueNode(const GroveImpl *grove,
4473
const AttributeValue *value,
4475
const TextIter &iter,
4476
size_t charIndex) const
4478
return new EntityCdataAttributeValueNode(grove, value, attIndex, iter,
4479
charIndex, entity_);
4483
Node *EntityAttributeOrigin
4484
::makeAttributeValueTokenNode(const GroveImpl *grove,
4485
const TokenizedAttributeValue *value,
4487
size_t tokenIndex) const
4489
return new EntityAttributeValueTokenNode(grove, value, attIndex,
4490
tokenIndex, entity_);
4493
Node *EntityAttributeOrigin
4494
::makeAttributeAsgnNode(const GroveImpl *grove,
4495
size_t attIndex) const
4497
return new EntityAttributeAsgnNode(grove, attIndex, entity_);
4500
AccessResult EntityAttributeOrigin
4501
::makeAttributeDefNode(const GroveImpl *grove,
4503
size_t attributeDefIdx) const
4505
if (entity_->notation() == 0)
4507
ptr.assign(new NotationAttributeDefNode(grove,
4508
*(entity_->notation()),
4513
Node *EntityAttributeOrigin::makeOriginNode(const GroveImpl *grove, size_t attIndex) const
4515
return makeAttributeAsgnNode(grove, attIndex);
4518
const void *EntityAttributeOrigin::attributeOriginId() const
4523
DoctypesAndLinktypesNamedNodeList
4524
::DoctypesAndLinktypesNamedNodeList(const GroveImpl *grove)
4525
: BaseNamedNodeList(grove, grove->generalSubstTable())
4529
NodeListPtr DoctypesAndLinktypesNamedNodeList::nodeList() const
4531
NodePtr tem(new DocumentTypeNode(grove(), grove()->governingDtd()));
4532
return new SiblingNodeList(tem);
4536
DoctypesAndLinktypesNamedNodeList
4537
::namedNodeU(const StringC &str, NodePtr &ptr) const
4539
if (grove()->governingDtd()->name() != str)
4541
ptr.assign(new DocumentTypeNode(grove(), grove()->governingDtd()));
4545
GeneralEntitiesNamedNodeList
4546
::GeneralEntitiesNamedNodeList(const GroveImpl *grove, const Dtd *dtd)
4547
: BaseNamedNodeList(grove, grove->entitySubstTable()), dtd_(dtd)
4551
NodeListPtr GeneralEntitiesNamedNodeList::nodeList() const
4553
return new EntitiesNodeList(grove(),
4554
dtd_->generalEntityIter());
4558
GeneralEntitiesNamedNodeList::namedNodeU(const StringC &str, NodePtr &ptr) const
4560
const Entity *entity
4561
= dtd_->lookupEntityTemp(0, str);
4564
ptr.assign(new EntityNode(grove(), entity));
4568
ParameterEntitiesNamedNodeList
4569
::ParameterEntitiesNamedNodeList(const GroveImpl *grove, const Dtd *dtd)
4570
: BaseNamedNodeList(grove, grove->entitySubstTable()), dtd_(dtd)
4574
NodeListPtr ParameterEntitiesNamedNodeList::nodeList() const
4576
return new EntitiesNodeList(grove(),
4577
dtd_->parameterEntityIter());
4581
ParameterEntitiesNamedNodeList::namedNodeU(const StringC &str, NodePtr &ptr) const
4583
const Entity *entity
4584
= dtd_->lookupEntityTemp(1, str);
4587
ptr.assign(new EntityNode(grove(), entity));
4592
DefaultedEntitiesNamedNodeList::namedNodeU(const StringC &str, NodePtr &ptr) const
4594
const Entity *entity
4595
= grove()->lookupDefaultedEntity(str);
4598
ptr.assign(new EntityNode(grove(), entity));
4603
DefaultedEntitiesNamedNodeList::nodeList() const
4605
return new EntitiesNodeList(grove(), grove()->defaultedEntityIter());
4608
NodeListPtr DocEntitiesNamedNodeList::nodeList() const
4610
return new DocEntitiesNodeList(grove());
4614
DocEntitiesNamedNodeList::namedNodeU(const StringC &str, NodePtr &ptr) const
4616
const Entity *entity
4617
= grove()->governingDtd()->lookupEntityTemp(0, str);
4618
// How I hate the default entity.
4620
if (!grove()->hasDefaultEntity())
4622
// Make sure that the value of complete
4623
// we look at is that before we looked up
4625
Boolean complete = grove()->complete();
4626
entity = grove()->lookupDefaultedEntity(str);
4631
if (!grove()->waitForMoreNodes())
4632
return accessTimeout;
4634
ptr.assign(new EntityNode(grove(), entity));
4639
ElementsNamedNodeList::namedNodeU(const StringC &str, NodePtr &ptr) const
4642
Boolean complete = grove()->complete();
4643
const ElementChunk *element = grove()->lookupElement(str);
4645
ptr.assign(new ElementNode(grove(), element));
4650
if (!grove()->waitForMoreNodes())
4651
return accessTimeout;
4656
NodeListPtr ElementsNamedNodeList::nodeList() const
4658
return new ElementsNodeList(grove(), grove()->root()->documentElement);
4661
ElementsNodeList::ElementsNodeList(const GroveImpl *grove,
4663
: grove_(grove), first_(first)
4667
AccessResult ElementsNodeList::first(NodePtr &ptr) const
4669
const Chunk *p = first_;
4671
while (p == grove_->completeLimit()) {
4672
if (!grove_->waitForMoreNodes())
4673
return accessTimeout;
4676
((ElementsNodeList *)this)->first_ = p;
4677
ptr.assign(new ElementNode(grove_, (const ElementChunk *)p));
4685
AccessResult ElementsNodeList::chunkRest(NodeListPtr &ptr) const
4687
const Chunk *p = first_;
4689
while (p == grove_->completeLimit()) {
4690
if (!grove_->waitForMoreNodes())
4691
return accessTimeout;
4695
((ElementsNodeList *)this)->first_ = p->after();
4697
ptr.assign(new ElementsNodeList(grove_, p->after()));
4705
// iter.next() gives first member of list that this represents
4707
EntitiesNodeList::EntitiesNodeList(const GroveImpl *grove,
4708
const Dtd::ConstEntityIter &iter)
4709
: grove_(grove), iter_(iter)
4713
AccessResult EntitiesNodeList::first(NodePtr &ptr) const
4715
Dtd::ConstEntityIter tem(iter_);
4716
const Entity *entity = tem.nextTemp();
4719
ptr.assign(new EntityNode(grove_, entity));
4723
AccessResult EntitiesNodeList::chunkRest(NodeListPtr &ptr) const
4725
if (canReuse(ptr)) {
4726
EntitiesNodeList *list = (EntitiesNodeList *)this;
4727
if (list->iter_.nextTemp() == 0)
4731
Dtd::ConstEntityIter tem(iter_);
4732
if (tem.nextTemp() == 0)
4734
ptr.assign(new EntitiesNodeList(grove_, tem));
4738
DocEntitiesNodeList::DocEntitiesNodeList(const GroveImpl *grove)
4739
: EntitiesNodeList(grove, grove->governingDtd()->generalEntityIter())
4743
AccessResult DocEntitiesNodeList::first(NodePtr &ptr) const
4745
AccessResult ret = EntitiesNodeList::first(ptr);
4746
if (ret != accessNull || !grove()->hasDefaultEntity())
4748
while (!grove()->complete())
4749
if (!grove()->waitForMoreNodes())
4750
return accessTimeout;
4751
Dtd::ConstEntityIter tem(grove()->defaultedEntityIter());
4752
const Entity *entity = tem.nextTemp();
4755
ptr.assign(new EntityNode(grove(), entity));
4759
AccessResult DocEntitiesNodeList::chunkRest(NodeListPtr &ptr) const
4761
AccessResult ret = EntitiesNodeList::chunkRest(ptr);
4762
if (ret != accessNull || !grove()->hasDefaultEntity())
4764
while (!grove()->complete())
4765
if (!grove()->waitForMoreNodes())
4766
return accessTimeout;
4767
Dtd::ConstEntityIter tem(grove()->defaultedEntityIter());
4768
const Entity *entity = tem.nextTemp();
4771
ptr.assign(new EntitiesNodeList(grove(), tem));
4775
NotationsNamedNodeList
4776
::NotationsNamedNodeList(const GroveImpl *grove, const Dtd *dtd)
4777
: BaseNamedNodeList(grove, grove->generalSubstTable()), dtd_(dtd)
4781
NodeListPtr NotationsNamedNodeList::nodeList() const
4783
return new NotationsNodeList(grove(),
4784
dtd_->notationIter());
4788
NotationsNamedNodeList::namedNodeU(const StringC &str, NodePtr &ptr) const
4790
const Notation *notation
4791
= dtd_->lookupNotationTemp(str);
4794
ptr.assign(new NotationNode(grove(), notation));
4799
// iter.next() gives first member of list that this represents
4801
NotationsNodeList::NotationsNodeList(const GroveImpl *grove,
4802
const Dtd::ConstNotationIter &iter)
4803
: grove_(grove), iter_(iter)
4807
AccessResult NotationsNodeList::first(NodePtr &ptr) const
4809
Dtd::ConstNotationIter tem(iter_);
4810
const Notation *notation = tem.nextTemp();
4813
ptr.assign(new NotationNode(grove_, notation));
4817
AccessResult NotationsNodeList::chunkRest(NodeListPtr &ptr) const
4819
if (canReuse(ptr)) {
4820
NotationsNodeList *list = (NotationsNodeList *)this;
4821
if (list->iter_.next().isNull())
4825
Dtd::ConstNotationIter tem(iter_);
4826
if (tem.nextTemp() == 0)
4828
ptr.assign(new NotationsNodeList(grove_, tem));
4832
NotationNode::NotationNode(const GroveImpl *grove,
4833
const Notation *notation)
4834
: BaseNode(grove), notation_(notation)
4838
AccessResult NotationNode::getOrigin(NodePtr &ptr) const
4840
ptr.assign(new DocumentTypeNode(grove(), grove()->governingDtd()));
4844
AccessResult NotationNode::getName(GroveString &str) const
4846
setString(str, notation_->name());
4850
AccessResult NotationNode::getExternalId(NodePtr &ptr) const
4852
ptr.assign(new NotationExternalIdNode(grove(), notation_));
4856
AccessResult NotationNode::getAttributeDefs(NamedNodeListPtr &ptr) const
4858
ptr.assign(new NotationAttributeDefsNamedNodeList(grove(), *notation_));
4862
AccessResult NotationNode::getLocation(Location &loc) const
4864
return grove()->proxifyLocation(notation_->defLocation(), loc);
4867
bool NotationNode::same(const BaseNode &node) const
4869
return node.same2(this);
4872
bool NotationNode::same2(const NotationNode *node) const
4874
return notation_ == node->notation_;
4877
void NotationNode::accept(NodeVisitor &visitor)
4879
visitor.notation(*this);
4882
unsigned long NotationNode::hash() const
4884
return (unsigned long)notation_;
4887
ExternalIdNode::ExternalIdNode(const GroveImpl *grove)
4892
AccessResult ExternalIdNode::getPublicId(GroveString &str) const
4894
const StringC *s = externalId().publicIdString();
4901
AccessResult ExternalIdNode::getSystemId(GroveString &str) const
4903
const StringC *s = externalId().systemIdString();
4910
AccessResult ExternalIdNode::getGeneratedSystemId(GroveString &str) const
4912
const StringC &s = externalId().effectiveSystemId();
4919
void ExternalIdNode::accept(NodeVisitor &visitor)
4921
visitor.externalId(*this);
4924
bool ExternalIdNode::same(const BaseNode &node) const
4926
return node.same2(this);
4929
bool ExternalIdNode::same2(const ExternalIdNode *node) const
4931
return &externalId() == &node->externalId();
4934
EntityExternalIdNode::EntityExternalIdNode(const GroveImpl *grove,
4935
const ExternalEntity *entity)
4936
: ExternalIdNode(grove), entity_(entity)
4940
const ExternalId &EntityExternalIdNode::externalId() const
4942
return entity_->externalId();
4945
AccessResult EntityExternalIdNode::getOrigin(NodePtr &ptr) const
4947
ptr.assign(new EntityNode(grove(), entity_));
4951
unsigned long EntityExternalIdNode::hash() const
4953
return secondHash((unsigned long)entity_);
4956
NotationExternalIdNode::NotationExternalIdNode(const GroveImpl *grove,
4957
const Notation *notation)
4958
: ExternalIdNode(grove), notation_(notation)
4962
const ExternalId &NotationExternalIdNode::externalId() const
4964
return notation_->externalId();
4967
AccessResult NotationExternalIdNode::getOrigin(NodePtr &ptr) const
4969
ptr.assign(new NotationNode(grove(), notation_));
4973
unsigned long NotationExternalIdNode::hash() const
4975
return secondHash((unsigned long)notation_);
4978
AccessResult ChunkNode::getParent(NodePtr &ptr) const
4980
if (!chunk_->origin)
4982
// This is needed because PiNodes in the prolog and
4983
// epilog don't have a parent but do have an origin.
4984
// Also for the document element.
4985
if ((const Chunk *)chunk()->origin == grove()->root())
4987
chunk_->origin->setNodePtrFirst(ptr, this);
4991
AccessResult ChunkNode::getTreeRoot(NodePtr &ptr) const
4994
&& (const Chunk *)chunk()->origin != grove()->root()
4995
// With invalid documents we might have elements in the epilog
4996
&& !grove()->root()->epilog
4997
&& grove()->root()->documentElement)
4998
return grove()->root()->documentElement->setNodePtrFirst(ptr, this);
4999
return Node::getTreeRoot(ptr);
5002
AccessResult ChunkNode::getOrigin(NodePtr &ptr) const
5004
if (!chunk_->origin)
5006
chunk_->origin->setNodePtrFirst(ptr, this);
5010
AccessResult ChunkNode::getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const
5012
if ((const Chunk *)chunk()->origin != grove()->root())
5013
name = ComponentName::idContent;
5014
else if ((const Chunk *)chunk() == grove()->root()->documentElement)
5015
name = ComponentName::idDocumentElement;
5018
if (chunk()->getFirstSibling(grove(), tem) == accessOK && tem == grove()->root()->prolog)
5019
name = ComponentName::idProlog;
5021
name = ComponentName::idEpilog;
5026
unsigned long ChunkNode::hash() const
5028
return (unsigned long)chunk_;
5031
bool ChunkNode::same(const BaseNode &node) const
5033
return node.same2(this);
5036
bool ChunkNode::same2(const ChunkNode *node) const
5038
return chunk_ == node->chunk_;
5041
BaseNode::~BaseNode()
5045
void BaseNode::addRef()
5050
void BaseNode::release()
5052
ASSERT(refCount_ != 0);
5053
if (--refCount_ == 0)
5057
unsigned BaseNode::groveIndex() const
5059
return grove_->groveIndex();
5062
bool BaseNode::operator==(const Node &node) const
5064
if (!sameGrove(node))
5066
return same((const BaseNode &)node);
5069
bool BaseNode::chunkContains(const Node &node) const
5071
if (!sameGrove(node))
5073
return same((const BaseNode &)node);
5076
bool BaseNode::inChunk(const DataNode *) const
5081
bool BaseNode::inChunk(const CdataAttributeValueNode *) const
5086
bool BaseNode::same2(const ChunkNode *) const
5091
bool BaseNode::same2(const DataNode *) const
5096
bool BaseNode::same2(const AttributeAsgnNode *) const
5101
bool BaseNode::same2(const AttributeValueTokenNode *) const
5106
bool BaseNode::same2(const CdataAttributeValueNode *) const
5111
bool BaseNode::same2(const EntityNode *) const
5116
bool BaseNode::same2(const NotationNode *) const
5121
bool BaseNode::same2(const ExternalIdNode *) const
5126
bool BaseNode::same2(const DocumentTypeNode *) const
5131
bool BaseNode::same2(const SgmlConstantsNode *) const
5136
bool BaseNode::same2(const MessageNode *) const
5141
bool BaseNode::same2(const ElementTypeNode *) const
5146
bool BaseNode::same2(const ModelGroupNode *) const
5151
bool BaseNode::same2(const ElementTokenNode *) const
5156
bool BaseNode::same2(const PcdataTokenNode *) const
5161
bool BaseNode::same2(const AttributeDefNode *) const
5166
bool BaseNode::same2(const DefaultEntityNode *) const
5171
AccessResult BaseNode::nextSibling(NodePtr &ptr) const
5173
return nextChunkSibling(ptr);
5176
AccessResult BaseNode::follow(NodeListPtr &ptr) const
5179
AccessResult ret = nextSibling(nd);
5182
ptr.assign(new SiblingNodeList(nd));
5185
ptr.assign(new BaseNodeList);
5194
AccessResult BaseNode::children(NodeListPtr &ptr) const
5197
AccessResult ret = firstChild(head);
5200
ptr.assign(new SiblingNodeList(head));
5203
ptr.assign(new BaseNodeList);
5212
AccessResult BaseNode::getOrigin(NodePtr &ptr) const
5214
return getParent(ptr);
5217
AccessResult BaseNode::getGroveRoot(NodePtr &ptr) const
5219
ptr.assign(new SgmlDocumentNode(grove(), grove()->root()));
5223
AccessResult BaseNode::getLocation(Location &) const
5228
bool BaseNode::queryInterface(IID iid, const void *&p) const
5230
if (iid == LocNode::iid) {
5231
const LocNode *ip = this;
5239
ForwardingChunk::setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const
5243
ASSERT(origin == forwardTo->origin);
5244
return forwardTo->setNodePtrFirst(ptr, node);
5248
ForwardingChunk::getFollowing(const GroveImpl *grove,
5249
const Chunk *&p, unsigned long &nNodes)
5252
AccessResult ret = Chunk::getFollowing(grove, p, nNodes);
5253
if (ret == accessOK)
5259
LocOriginChunk::getFollowing(const GroveImpl *grove,
5260
const Chunk *&p, unsigned long &nNodes)
5263
AccessResult ret = Chunk::getFollowing(grove, p, nNodes);
5264
if (ret == accessOK)
5269
AccessResult LocOriginChunk::setNodePtrFirst(NodePtr &ptr, const BaseNode *node) const
5271
return ((const Chunk *)(this + 1))->setNodePtrFirst(ptr, node);
5274
AccessResult LocOriginChunk::setNodePtrFirst(NodePtr &ptr, const ElementNode *node) const
5276
return ((const Chunk *)(this + 1))->setNodePtrFirst(ptr, node);
5279
AccessResult LocOriginChunk::setNodePtrFirst(NodePtr &ptr, const DataNode *node) const
5281
return ((const Chunk *)(this + 1))->setNodePtrFirst(ptr, node);
5284
const Chunk *LocOriginChunk::after() const
5289
Boolean LocOriginChunk::getLocOrigin(const Origin *&ret) const
5296
Chunk::setNodePtrFirst(NodePtr &ptr, const ElementNode *node) const
5298
return setNodePtrFirst(ptr, (const BaseNode *)node);
5302
Chunk::setNodePtrFirst(NodePtr &ptr, const DataNode *node) const
5304
return setNodePtrFirst(ptr, (const BaseNode *)node);
5307
const StringC *Chunk::id() const
5312
AccessResult Chunk::getFollowing(const GroveImpl *grove,
5313
const Chunk *&f, unsigned long &n) const
5315
const Chunk *p = after();
5316
while (p == grove->completeLimit())
5317
if (!grove->waitForMoreNodes())
5318
return accessTimeout;
5319
if (p->origin != origin)
5326
AccessResult Chunk::getFirstSibling(const GroveImpl *grove,
5327
const Chunk *&p) const
5329
if ((const Chunk *)origin == grove->root())
5330
return accessNotInClass;
5331
p = origin->after();
5335
Boolean Chunk::getLocOrigin(const Origin *&) const
5340
// ------------------------------ dev --------------------------------
5342
// -- CLASS IMP: ElementTypeNode
5344
AccessResult ElementTypeNode::getOrigin(NodePtr &ptr) const
5346
ptr.assign(new DocumentTypeNode(grove(), grove()->governingDtd()));
5350
AccessResult ElementTypeNode::getLocation(Location &loc) const
5352
const ElementDefinition *def = elementType_.definition();
5355
return grove()->proxifyLocation(def->location(), loc);
5358
AccessResult ElementTypeNode::getGi(GroveString &str) const
5360
setString(str, elementType_.name());
5364
AccessResult ElementTypeNode::getModelGroup(NodePtr &ptr) const
5366
const ElementDefinition *def = elementType_.definition();
5367
if (def == 0 || def->declaredContent() != ElementDefinition::modelGroup)
5369
ptr.assign(new ModelGroupNode(grove(),
5371
*(def->compiledModelGroup()->modelGroup())));
5375
AccessResult ElementTypeNode::getContentType(Node::ContentType::Enum &enumId) const
5377
const ElementDefinition *def = elementType_.definition();
5380
switch (def->declaredContent() ) {
5381
case ElementDefinition::modelGroup:
5382
enumId = ContentType::modelgrp;
5384
case ElementDefinition::any:
5385
enumId = ContentType::any;
5387
case ElementDefinition::cdata:
5388
enumId = ContentType::cdata;
5390
case ElementDefinition::rcdata:
5391
enumId = ContentType::rcdata;
5393
case ElementDefinition::empty:
5394
enumId = ContentType::empty;
5402
AccessResult ElementTypeNode::getExclusions(GroveStringListPtr &sl) const
5404
const ElementDefinition *def = elementType_.definition();
5406
|| (def->declaredContent() != ElementDefinition::modelGroup
5407
&& def->declaredContent() != ElementDefinition::any))
5409
sl.assign(new GroveStringList);
5411
for (size_t i = 0; i < def->nExclusions(); i++ ) {
5412
setString(str, def->exclusion(i)->name());
5418
AccessResult ElementTypeNode::getInclusions(GroveStringListPtr &sl) const
5420
const ElementDefinition *def = elementType_.definition();
5422
|| (def->declaredContent() != ElementDefinition::modelGroup
5423
&& def->declaredContent() != ElementDefinition::any))
5425
sl.assign(new GroveStringList);
5427
for (size_t i = 0; i < def->nInclusions(); i++ ) {
5428
setString(str, def->inclusion(i)->name());
5434
AccessResult ElementTypeNode::getOmitEndTag(bool &f) const
5436
const ElementDefinition *def = elementType_.definition();
5437
if (def == 0 || !def->omittedTagSpec())
5439
f = def->canOmitEndTag();
5443
AccessResult ElementTypeNode::getOmitStartTag(bool &f) const
5445
const ElementDefinition *def = elementType_.definition();
5446
if (def == 0 || !def->omittedTagSpec())
5448
f = def->canOmitStartTag();
5452
AccessResult ElementTypeNode::getAttributeDefs(NamedNodeListPtr &ptr) const
5454
ptr.assign(new ElementTypeAttributeDefsNamedNodeList(grove(), elementType_));
5458
bool ElementTypeNode::same(const BaseNode &node) const
5460
return node.same2(this);
5463
bool ElementTypeNode::same2(const ElementTypeNode *node) const
5465
return &elementType_ == &(node->elementType());
5468
void ElementTypeNode::accept(NodeVisitor &visitor)
5470
visitor.elementType(*this);
5473
unsigned long ElementTypeNode::hash() const
5475
return (unsigned long)&elementType_;
5478
// -- CLASS IMP: ElementTypesNodeList
5480
ElementTypesNodeList::ElementTypesNodeList( const GroveImpl *grove,
5481
const Dtd::ConstElementTypeIter &iter )
5482
: grove_(grove), iter_(iter)
5486
AccessResult ElementTypesNodeList::first(NodePtr &ptr) const
5488
Dtd::ConstElementTypeIter tem(iter_);
5489
const ElementType *elementType = tem.next();
5492
ptr.assign(new ElementTypeNode(grove_, *elementType));
5496
AccessResult ElementTypesNodeList::chunkRest(NodeListPtr &ptr) const
5498
if (canReuse(ptr)) {
5499
ElementTypesNodeList *list = (ElementTypesNodeList *)this;
5500
if (list->iter_.next() == 0)
5504
Dtd::ConstElementTypeIter tem(iter_);
5505
if (tem.next() == 0)
5507
ptr.assign(new ElementTypesNodeList(grove_, tem));
5511
// -- CLASS IMP: ElementTypesNamedNodeList
5513
ElementTypesNamedNodeList::ElementTypesNamedNodeList(const GroveImpl *grove, const Dtd *dtd)
5514
: BaseNamedNodeList( grove, grove->generalSubstTable() ), dtd_(dtd)
5518
NodeListPtr ElementTypesNamedNodeList::nodeList() const
5520
return new ElementTypesNodeList(grove(), dtd_->elementTypeIter());
5523
AccessResult ElementTypesNamedNodeList::namedNodeU(const StringC &str, NodePtr &ptr) const
5525
const ElementType *elementType = dtd_->lookupElementType(str); // ? Temp
5528
ptr.assign(new ElementTypeNode(grove(), *elementType));
5532
// -- CLASS IMP: ContentTokenNodeBase
5534
ContentTokenNodeBase::ContentTokenNodeBase(const GroveImpl *grove,
5535
const ElementType &elementType,
5536
ModelGroupNode *parentModelGroupNode)
5537
: BaseNode(grove), elementType_(elementType), parentModelGroupNode_(parentModelGroupNode)
5539
if (parentModelGroupNode_ != 0)
5540
parentModelGroupNode_->addRef();
5543
ContentTokenNodeBase::~ContentTokenNodeBase()
5545
if (parentModelGroupNode_ != 0)
5546
parentModelGroupNode_->release();
5549
AccessResult ContentTokenNodeBase::getOrigin(NodePtr &ptr) const
5551
if (parentModelGroupNode_ != 0)
5552
ptr.assign(parentModelGroupNode_);
5554
ptr.assign(new ElementTypeNode(grove(), elementType_));
5558
AccessResult ContentTokenNodeBase::getLocation(Location &loc) const
5560
const ElementDefinition *def = elementType_.definition();
5563
return grove()->proxifyLocation(def->location(), loc);
5566
// -- CLASS IMP: ElementTokenNode
5568
AccessResult ElementTokenNode::getGi(GroveString &str) const
5570
assert(elementToken_.elementType() != 0);
5571
setString(str, elementToken_.elementType()->name());
5575
AccessResult ElementTokenNode::getOccurIndicator(Node::OccurIndicator::Enum &occur) const
5577
switch (elementToken_.occurrenceIndicator())
5579
case ContentToken::opt:
5580
occur = OccurIndicator::opt;
5582
case ContentToken::plus:
5583
occur = OccurIndicator::plus;
5585
case ContentToken::rep:
5586
occur = OccurIndicator::rep;
5588
case ContentToken::none:
5596
bool ElementTokenNode::same(const BaseNode &node) const
5598
return node.same2(this);
5601
bool ElementTokenNode::same2(const ElementTokenNode *node) const
5603
return &elementToken_ == &(node->elementToken());
5606
void ElementTokenNode::accept(NodeVisitor &visitor)
5608
visitor.elementToken(*this);
5611
unsigned long ElementTokenNode::hash() const
5613
return (unsigned long)&elementToken_;
5616
// -- CLASS IMP: PcdataTokenNode
5618
bool PcdataTokenNode::same(const BaseNode &node) const
5620
return node.same2(this);
5623
bool PcdataTokenNode::same2(const PcdataTokenNode *node) const
5625
return &pcdataToken_ == &(node->pcdataToken());
5628
void PcdataTokenNode::accept(NodeVisitor &visitor)
5630
visitor.pcdataToken(*this);
5633
unsigned long PcdataTokenNode::hash() const
5635
return (unsigned long)&pcdataToken_;
5638
// -- CLASS IMP: ModelGroupNode
5640
AccessResult ModelGroupNode::getOriginToSubnodeRelPropertyName(ComponentName::Id &name) const
5642
name = parentModelGroupNode_ == 0
5643
? ComponentName::idModelGroup
5644
: ComponentName::idContentTokens;
5648
AccessResult ModelGroupNode::getConnector(Node::Connector::Enum &conn) const
5650
switch (modelGroup_.connector())
5652
case ModelGroup::andConnector:
5653
conn = Connector::and_;
5655
case ModelGroup::orConnector:
5656
conn = Connector::or_;
5658
case ModelGroup::seqConnector:
5659
conn = Connector::seq;
5667
AccessResult ModelGroupNode::getOccurIndicator(Node::OccurIndicator::Enum &occur) const
5669
switch (modelGroup_.occurrenceIndicator()) {
5670
case ContentToken::opt:
5671
occur = OccurIndicator::opt;
5673
case ContentToken::plus:
5674
occur = OccurIndicator::plus;
5676
case ContentToken::rep:
5677
occur = OccurIndicator::rep;
5679
case ContentToken::none:
5687
AccessResult ModelGroupNode::getContentTokens(NodeListPtr &ptr) const
5689
ptr.assign(new ContentTokenNodeList(grove(), *(ModelGroupNode *)this));
5693
void ModelGroupNode::makeNode(NodePtr &ptr, unsigned contentTokenIdx)
5695
assert( contentTokenIdx < modelGroup_.nMembers());
5696
const ContentToken &contentToken = modelGroup_.member(contentTokenIdx);
5697
const ModelGroup *asModelGroup = contentToken.asModelGroup();
5698
if (asModelGroup != 0)
5699
ptr.assign(new ModelGroupNode(grove(),
5705
const LeafContentToken *asLeafContentToken = contentToken.asLeafContentToken();
5706
if (asLeafContentToken != 0)
5707
if (asLeafContentToken->elementType() != 0)
5708
ptr.assign(new ElementTokenNode(grove(),
5710
*(const ElementToken*)asLeafContentToken,
5712
else if (asLeafContentToken->occurrenceIndicator() == ContentToken::rep)
5713
ptr.assign(new PcdataTokenNode(grove(),
5715
*(const PcdataToken*)asLeafContentToken,
5722
bool ModelGroupNode::same(const BaseNode &node) const
5724
return node.same2(this);
5727
bool ModelGroupNode::same2(const ModelGroupNode *node) const
5729
return &modelGroup_ == &(node->modelGroup());
5732
void ModelGroupNode::accept(NodeVisitor &visitor)
5734
visitor.modelGroup(*this);
5737
unsigned long ModelGroupNode::hash() const
5739
return (unsigned long)&modelGroup_;
5742
// -- CLASS IMP: ContentTokenNodeList
5744
ContentTokenNodeList::ContentTokenNodeList(const GroveImpl *grove,
5745
ModelGroupNode &modelGroupNode,
5746
unsigned firstTokenIdx)
5747
: grove_(grove), modelGroupNode_(modelGroupNode), firstTokenIdx_(firstTokenIdx)
5751
AccessResult ContentTokenNodeList::next()
5753
if (++firstTokenIdx_ >= modelGroupNode_.modelGroup().nMembers())
5758
AccessResult ContentTokenNodeList::first(NodePtr &ptr) const
5760
if (firstTokenIdx_ < modelGroupNode_.modelGroup().nMembers())
5761
modelGroupNode_.makeNode(ptr, firstTokenIdx_);
5767
AccessResult ContentTokenNodeList::chunkRest(NodeListPtr &ptr) const
5769
if (canReuse(ptr)) {
5770
ContentTokenNodeList *list = (ContentTokenNodeList *)this;
5771
return list->next();
5773
unsigned firstTokenIdx = firstTokenIdx_;
5774
if (++firstTokenIdx >= modelGroupNode_.modelGroup().nMembers())
5776
ptr.assign(new ContentTokenNodeList(grove_, modelGroupNode_, firstTokenIdx));
5780
// class IMP: AttributeDefOrigin
5783
AttributeDefOrigin::makeAttributeValueNode(const GroveImpl *grove,
5785
const AttributeValue *value) const
5790
switch (value->info(text, str)) {
5791
case AttributeValue::tokenized:
5792
ptr.assign(makeAttributeValueTokenNode(grove,
5793
(const TokenizedAttributeValue *)value,
5796
case AttributeValue::cdata:
5798
TextIter iter(*text);
5799
if (!CdataAttributeValueNode::skipBoring(iter)) {
5804
ptr.assign(makeCdataAttributeValueNode(grove, value,
5817
AttributeDefOrigin::makeAttributeValueNodeList(const GroveImpl *grove,
5819
const AttributeValue *value = 0) const
5822
AccessResult result;
5823
result = makeAttributeValueNode(grove, nodePtr, value);
5824
if (result == accessOK)
5825
ptr.assign(nodePtr.operator->() == 0 ? new BaseNodeList : new SiblingNodeList(nodePtr));
5829
AccessResult AttributeDefOrigin::makeAttributeDefNode(const GroveImpl *grove,
5831
const StringC &name) const
5833
if (attDefList() == 0)
5835
for (size_t i = 0; i < attDefList()->size(); i++)
5836
if (attDefList()->def(i)->name() == name)
5838
return makeAttributeDefNode(grove, ptr, i);
5844
// class IMP: ElementTypeAttributeDefOrigin
5846
ElementTypeAttributeDefOrigin::ElementTypeAttributeDefOrigin(const ElementType *elementType)
5847
: elementType_(elementType)
5851
const AttributeDefinitionList *ElementTypeAttributeDefOrigin::attDefList() const
5853
return elementType_->attributeDefTemp();
5856
AccessResult ElementTypeAttributeDefOrigin::makeAttributeDefNode(const GroveImpl *grove,
5858
size_t attributeDefIdx) const
5860
ptr.assign(new ElementTypeAttributeDefNode(grove, *elementType_, attributeDefIdx));
5864
AccessResult ElementTypeAttributeDefOrigin::makeAttributeDefList(const GroveImpl *grove,
5866
size_t firstAttDefIdx) const
5868
ptr.assign(new ElementTypeAttributeDefsNodeList(grove,
5874
Node *ElementTypeAttributeDefOrigin
5875
::makeCdataAttributeValueNode(const GroveImpl *grove,
5876
const AttributeValue *value,
5878
const TextIter &iter,
5879
size_t charIndex) const
5881
return new ElementTypeCdataAttributeValueNode(grove, value, attIndex, iter,
5882
charIndex, elementType_);
5886
Node *ElementTypeAttributeDefOrigin
5887
::makeAttributeValueTokenNode(const GroveImpl *grove,
5888
const TokenizedAttributeValue *value,
5890
size_t tokenIndex) const
5892
return new ElementTypeAttributeValueTokenNode(grove, value, attIndex,
5893
tokenIndex, elementType_);
5896
Node *ElementTypeAttributeDefOrigin::makeOriginNode(const GroveImpl *grove, size_t) const
5898
return new ElementTypeAttributeDefNode(grove, *elementType_, attIndex_);
5901
const void *ElementTypeAttributeDefOrigin::attributeOriginId() const
5903
return elementType_;
5906
// class IMP: NotationAttributeDefOrigin
5908
NotationAttributeDefOrigin::NotationAttributeDefOrigin(const Notation *notation)
5909
: notation_(notation)
5913
const AttributeDefinitionList *NotationAttributeDefOrigin::attDefList() const
5915
return notation_->attributeDefTemp();
5918
AccessResult NotationAttributeDefOrigin::makeAttributeDefNode(const GroveImpl *grove,
5920
size_t attributeDefIdx) const
5922
ptr.assign(new NotationAttributeDefNode(grove, *notation_, attributeDefIdx));
5926
AccessResult NotationAttributeDefOrigin::makeAttributeDefList(const GroveImpl *grove,
5928
size_t firstAttDefIdx) const
5930
ptr.assign(new NotationAttributeDefsNodeList(grove,
5936
Node *NotationAttributeDefOrigin
5937
::makeCdataAttributeValueNode(const GroveImpl *grove,
5938
const AttributeValue *value,
5940
const TextIter &iter,
5941
size_t charIndex) const
5943
return new NotationCdataAttributeValueNode(grove, value, attIndex, iter,
5944
charIndex, notation_);
5948
Node *NotationAttributeDefOrigin
5949
::makeAttributeValueTokenNode(const GroveImpl *grove,
5950
const TokenizedAttributeValue *value,
5952
size_t tokenIndex) const
5954
return new NotationAttributeValueTokenNode(grove, value, attIndex,
5955
tokenIndex, notation_);
5958
Node *NotationAttributeDefOrigin::makeOriginNode(const GroveImpl *grove, size_t) const
5960
return new NotationAttributeDefNode(grove, *notation_, attIndex_);
5963
const void *NotationAttributeDefOrigin::attributeOriginId() const
5968
// class IMP: AttributeDefNode
5970
AccessResult AttributeDefNode::getOrigin(NodePtr &ptr) const
5972
ptr.assign(makeOriginNode(grove(), attIndex_));
5976
AccessResult AttributeDefNode::getName(GroveString &str) const
5978
setString(str, attDefList()->def(attIndex_)->name());
5982
AccessResult AttributeDefNode::getDeclValueType(Node::DeclValueType::Enum &dvt) const
5984
AttributeDefinitionDesc desc;
5985
attDefList()->def(attIndex_)->getDesc(desc);
5986
switch (desc.declaredValue)
5988
case AttributeDefinitionDesc::cdata:
5989
dvt = DeclValueType::cdata;
5991
case AttributeDefinitionDesc::name:
5992
dvt = DeclValueType::name;
5994
case AttributeDefinitionDesc::number:
5995
dvt = DeclValueType::number;
5997
case AttributeDefinitionDesc::nmtoken:
5998
dvt = DeclValueType::nmtoken;
6000
case AttributeDefinitionDesc::nutoken:
6001
dvt = DeclValueType::nutoken;
6003
case AttributeDefinitionDesc::entity:
6004
dvt = DeclValueType::entity;
6006
case AttributeDefinitionDesc::idref:
6007
dvt = DeclValueType::idref;
6009
case AttributeDefinitionDesc::names:
6010
dvt = DeclValueType::names;
6012
case AttributeDefinitionDesc::numbers:
6013
dvt = DeclValueType::numbers;
6015
case AttributeDefinitionDesc::nmtokens:
6016
dvt = DeclValueType::nmtokens;
6018
case AttributeDefinitionDesc::nutokens:
6019
dvt = DeclValueType::nutokens;
6021
case AttributeDefinitionDesc::entities:
6022
dvt = DeclValueType::entities;
6024
case AttributeDefinitionDesc::idrefs:
6025
dvt = DeclValueType::idrefs;
6027
case AttributeDefinitionDesc::id:
6028
dvt = DeclValueType::id;
6030
case AttributeDefinitionDesc::notation:
6031
dvt = DeclValueType::notation;
6033
case AttributeDefinitionDesc::nameTokenGroup:
6034
dvt = DeclValueType::nmtkgrp;
6042
AccessResult AttributeDefNode::getDefaultValueType(Node::DefaultValueType::Enum &dvt) const
6044
AttributeDefinitionDesc desc;
6045
attDefList()->def(attIndex_)->getDesc(desc);
6046
switch (desc.defaultValueType)
6048
case AttributeDefinitionDesc::required:
6049
dvt = DefaultValueType::required;
6051
case AttributeDefinitionDesc::current:
6052
dvt = DefaultValueType::current;
6054
case AttributeDefinitionDesc::implied:
6055
dvt = DefaultValueType::implied;
6057
case AttributeDefinitionDesc::conref:
6058
dvt = DefaultValueType::conref;
6060
case AttributeDefinitionDesc::defaulted:
6061
dvt = DefaultValueType::value;
6063
case AttributeDefinitionDesc::fixed:
6064
dvt = DefaultValueType::fixed;
6072
AccessResult AttributeDefNode::getTokens(GroveStringListPtr &tokens) const
6074
AttributeDefinitionDesc desc;
6075
attDefList()->def(attIndex_)->getDesc(desc);
6076
if (desc.declaredValue != AttributeDefinitionDesc::notation
6077
&& desc.declaredValue != AttributeDefinitionDesc::nameTokenGroup)
6079
tokens.assign(new GroveStringList);
6081
for (size_t i = 0; i < desc.allowedValues.size(); i++)
6083
setString(str, desc.allowedValues[i]);
6084
tokens->append(str);
6089
AccessResult AttributeDefNode::getCurrentAttributeIndex(long &index) const
6091
AttributeDefinitionDesc desc;
6092
attDefList()->def(attIndex_)->getDesc(desc);
6093
if (desc.defaultValueType != AttributeDefinitionDesc::current)
6095
index = desc.currentIndex;
6099
void AttributeDefNode::accept(NodeVisitor &visitor)
6101
visitor.attributeDef(*this);
6104
bool AttributeDefNode::same(const BaseNode &node) const
6106
return node.same2(this);
6109
bool AttributeDefNode::same2(const AttributeDefNode *node) const
6111
return (attributeOriginId() == node->attributeOriginId()
6112
&& attIndex_ == node->attIndex());
6115
unsigned long AttributeDefNode::hash() const
6117
unsigned long n = (unsigned long)attributeOriginId();
6118
return secondHash(n + attIndex_);
6121
// class IMP: ElementTypeAttributeDefNode
6123
AccessResult ElementTypeAttributeDefNode::getCurrentGroup(NodeListPtr &ptr) const
6125
AttributeDefinitionDesc desc;
6126
attDefList()->def(attIndex_)->getDesc(desc);
6127
if (desc.defaultValueType != AttributeDefinitionDesc::current)
6130
new ElementTypeCurrentGroupAttributeDefsNodeList(grove(),
6131
grove()->governingDtd()->elementTypeIter(),
6132
desc.currentIndex));
6136
AccessResult ElementTypeAttributeDefNode::getLocation(Location &loc) const
6138
const ElementDefinition *def = elementType_->definition();
6141
return grove()->proxifyLocation(def->location(), loc);
6144
AccessResult ElementTypeAttributeDefNode::getDefaultValue(NodeListPtr &ptr) const
6146
AttributeDefinitionDesc desc;
6147
attDefList()->def(attIndex_)->getDesc(desc);
6148
const AttributeValue *value = desc.defaultValue.pointer();
6149
return makeAttributeValueNodeList(grove(), ptr, value);
6152
// class IMP: NotationAttributeDefNode
6154
AccessResult NotationAttributeDefNode::getCurrentGroup(NodeListPtr &ptr) const
6156
AttributeDefinitionDesc desc;
6157
attDefList()->def(attIndex_)->getDesc(desc);
6158
if (desc.defaultValueType != AttributeDefinitionDesc::current)
6161
nodePtr.assign(new NotationAttributeDefNode(grove(), *notation_, attIndex_));
6162
ptr.assign(new SiblingNodeList(nodePtr));
6166
AccessResult NotationAttributeDefNode::getLocation(Location &loc) const
6168
return grove()->proxifyLocation(notation_->defLocation(), loc);
6171
// -- CLASS IMP: AttributeDefsNodeList
6173
bool AttributeDefsNodeList::inList(size_t attIndex) const
6175
if (attDefList() == 0 || attIndex >= attDefList()->size())
6180
AccessResult AttributeDefsNodeList::first(NodePtr &ptr) const
6182
return inList(attIndex_)
6183
? makeAttributeDefNode(grove_, ptr, attIndex_)
6187
AccessResult AttributeDefsNodeList::chunkRest(NodeListPtr &ptr) const
6189
if (canReuse(ptr)) {
6190
AttributeDefsNodeList *list = (AttributeDefsNodeList *)this;
6191
if (list->inList(list->attIndex_)) {
6192
++(list->attIndex_);
6197
return inList(attIndex_)
6198
? makeAttributeDefList(grove_, ptr, attIndex_+1)
6202
// -- CLASS IMP: AttributeDefsNamedNodeList
6204
NodeListPtr AttributeDefsNamedNodeList::nodeList() const
6207
makeAttributeDefList(grove(), ptr, 0);
6211
AccessResult AttributeDefsNamedNodeList::namedNodeU(const StringC &str, NodePtr &ptr) const
6213
return makeAttributeDefNode(grove(), ptr, str);
6216
// -- CLASS IMP: ElementTypeCurrentGroupAttributeDefsNodeList
6218
ElementTypeCurrentGroupAttributeDefsNodeList
6219
::ElementTypeCurrentGroupAttributeDefsNodeList(const GroveImpl *grove,
6220
const Dtd::ConstElementTypeIter &iter,
6221
size_t currentGroupIndex)
6222
: grove_(grove), iter_(iter), currentGroupIndex_(currentGroupIndex), attIndex_(0)
6224
elementType_ = iter_.next();
6228
bool ElementTypeCurrentGroupAttributeDefsNodeList::next(Dtd::ConstElementTypeIter &iter,
6229
const ElementType *&elementType,
6231
bool incrementFirst) const
6235
while (elementType != 0) {
6236
if (attIndex >= elementType->attributeDefTemp()->size() ) {
6238
elementType = iter.next();
6239
} while(elementType != 0 && !elementType->attributeDefTemp()->anyCurrent());
6243
if (elementType->attributeDefTemp()->def(attIndex)->isCurrent()) {
6244
AttributeDefinitionDesc desc;
6245
elementType->attributeDefTemp()->def(attIndex)->getDesc(desc);
6246
if (desc.currentIndex == currentGroupIndex_)
6252
return elementType != 0 ? true : false;
6255
AccessResult ElementTypeCurrentGroupAttributeDefsNodeList::first(NodePtr &ptr) const
6257
if (elementType_ == 0)
6259
ptr.assign(new ElementTypeAttributeDefNode(grove_,
6265
AccessResult ElementTypeCurrentGroupAttributeDefsNodeList::chunkRest(NodeListPtr &ptr) const
6267
if (elementType_ == 0)
6269
if (canReuse(ptr)) {
6270
ElementTypeCurrentGroupAttributeDefsNodeList *list
6271
= (ElementTypeCurrentGroupAttributeDefsNodeList *)this;
6275
Dtd::ConstElementTypeIter iter(iter_);
6276
const ElementType *elementType = elementType_;
6277
size_t attIndex = attIndex_;
6278
next(iter, elementType, attIndex);
6279
ptr.assign(new ElementTypeCurrentGroupAttributeDefsNodeList(grove_,
6283
currentGroupIndex_));
6288
// ------------------------------ dev end --------------------------------
6294
#include "grove_inst.cxx"