1 // Copyright (c) 1996 James Clark
2 // See the file COPYING for copying permission.
3 #pragma ident "%Z%%M% %I% %E% SMI"
10 #include "ArcEngine.h"
11 #include "ArcProcessor.h"
15 #include "ArcEngineMessages.h"
16 #include "MessageArg.h"
17 #include "ParserOptions.h"
18 #include "SgmlParser.h"
19 #include "Allocator.h"
20 #include "LinkProcess.h"
24 namespace SP_NAMESPACE
{
27 static const size_t sizes
[] = {
28 sizeof(StartElementEvent
),
29 sizeof(EndElementEvent
),
30 sizeof(ImmediateDataEvent
),
31 sizeof(SdataEntityEvent
),
32 sizeof(EndPrologEvent
),
33 sizeof(CdataEntityEvent
),
34 sizeof(SdataEntityEvent
),
35 sizeof(ExternalDataEntityEvent
),
40 size_t maxSize(const size_t *v
, size_t n
)
43 for (size_t i
= 0; i
< n
; i
++) {
50 const unsigned invalidAtt
= unsigned(-1);
51 const unsigned contentPseudoAtt
= unsigned(-2);
53 class DelegateEventHandler
: public EventHandler
{
55 #define EVENT(C, f) void f(C *ev) { delegateTo_->f(ev); }
59 EventHandler
*delegateTo_
;
62 class QueueEventHandler
: public EventHandler
, public IQueue
<Event
> {
64 #define EVENT(C, f) void f(C *ev) { ev->copyData(); append(ev); }
69 // This just passes through messages.
71 class NullEventHandler
: public EventHandler
{
73 NullEventHandler(Messenger
&mgr
) : mgr_(&mgr
) { }
74 void message(MessageEvent
*event
) {
75 mgr_
->dispatchMessage(event
->message());
81 class ArcEngineImpl
: public DelegateEventHandler
, private Messenger
{
83 ArcEngineImpl(Messenger
&mgr
,
84 const SgmlParser
*parser
,
85 ArcDirector
&director
,
86 const volatile sig_atomic_t *cancelPtr
,
88 const Vector
<StringC
> &name
,
89 const SubstTable
<Char
> *table
);
91 void sgmlDecl(SgmlDeclEvent
*);
92 void appinfo(AppinfoEvent
*);
93 void startElement(StartElementEvent
*);
94 void endElement(EndElementEvent
*);
95 void data(DataEvent
*);
96 void sdataEntity(SdataEntityEvent
*);
97 void externalDataEntity(ExternalDataEntityEvent
*);
99 void endProlog(EndPrologEvent
*);
100 void startDtd(StartDtdEvent
*);
101 void endDtd(EndDtdEvent
*);
102 void startLpd(StartLpdEvent
*);
103 void endLpd(EndLpdEvent
*);
104 void uselink(UselinkEvent
*);
105 size_t nBases() const { return arcProcessors_
.size(); }
106 EventHandler
*delegateHandler() { return eventHandler_
; }
108 void dispatchMessage(const Message
&);
109 void dispatchMessage(Message
&);
110 void initMessage(Message
&);
112 EventHandler
*eventHandler_
;
113 NCVector
<ArcProcessor
> arcProcessors_
;
115 ConstPtr
<Syntax
> syntax_
;
119 QueueEventHandler eventQueue_
;
120 NullEventHandler nullHandler_
;
121 const SgmlParser
*parser_
;
122 Location currentLocation_
;
123 unsigned gatheringContent_
;
125 unsigned startAgain_
;
128 const AttributeList
*linkAttributes_
;
129 LinkProcess linkProcess_
;
130 Boolean haveLinkProcess_
;
131 Vector
<StringC
> docName_
;
132 ArcDirector
*director_
;
134 const volatile sig_atomic_t *cancelPtr_
;
138 void ArcEngine::parseAll(SgmlParser
&parser
,
140 ArcDirector
&director
,
141 const volatile sig_atomic_t *cancelPtr
)
143 ArcEngineImpl
wrap(mgr
, &parser
, director
, cancelPtr
,
144 0, Vector
<StringC
>(), 0);
145 parser
.parseAll(wrap
, cancelPtr
);
149 SelectOneArcDirector::arcEventHandler(const Notation
*,
150 const Vector
<StringC
> &name
,
151 const SubstTable
<Char
> *table
)
153 if (name
.size() != select_
.size())
155 for (size_t i
= 0; i
< name
.size(); i
++) {
156 StringC
tem(select_
[i
]);
164 void SelectOneArcDirector::dispatchMessage(const Message
&msg
)
166 eh_
->message(new MessageEvent(msg
));
169 void SelectOneArcDirector::dispatchMessage(Message
&msg
)
171 eh_
->message(new MessageEvent(msg
));
174 ArcEngineImpl::ArcEngineImpl(Messenger
&mgr
,
175 const SgmlParser
*parser
,
176 ArcDirector
&director
,
177 const volatile sig_atomic_t *cancelPtr
,
178 const Notation
*notation
,
179 const Vector
<StringC
> &docName
,
180 const SubstTable
<Char
> *table
)
182 : director_(&director
), mgr_(&mgr
), cancelPtr_(cancelPtr
),
183 parser_(parser
), stage_(0),
184 gatheringContent_(0), startAgain_(0), haveLinkProcess_(0),
185 alloc_(maxSize(sizes
, SIZEOF(sizes
)), 50),
186 nullHandler_(mgr
), docName_(docName
)
188 eventHandler_
= director
.arcEventHandler(notation
, docName
, table
);
190 eventHandler_
= &nullHandler_
;
191 delegateTo_
= eventHandler_
;
194 ArcEngineImpl::~ArcEngineImpl()
196 for (size_t i
= 0; i
< arcProcessors_
.size(); i
++)
197 if (arcProcessors_
[i
].valid())
198 arcProcessors_
[i
].checkIdrefs();
201 void ArcEngineImpl::appinfo(AppinfoEvent
*event
)
204 if (event
->literal(str
))
206 DelegateEventHandler::appinfo(event
);
209 void ArcEngineImpl::pi(PiEvent
*event
)
211 currentLocation_
= event
->location();
214 && event
->dataLength() > is10744_
.size() + 1) {
217 for (size_t j
= 0; j
< is10744_
.size() && match
; i
++, j
++)
218 if ((*syntax_
->generalSubstTable())[event
->data()[i
]] != is10744_
[j
])
220 if (!syntax_
->isS(event
->data()[i
]))
224 } while (i
< event
->dataLength() && syntax_
->isS(event
->data()[i
]));
225 for (size_t j
= 0; j
< arcBase_
.size() && match
; i
++, j
++)
226 if (i
>= event
->dataLength()
227 || (*syntax_
->generalSubstTable())[event
->data()[i
]] != arcBase_
[j
])
229 if (i
>= event
->dataLength() || !syntax_
->isS(event
->data()[i
]))
232 size_t dataLength
= event
->dataLength();
233 const Char
*data
= event
->data();
235 while (i
< dataLength
&& syntax_
->isS(data
[i
]))
240 while (i
< dataLength
&& !syntax_
->isS(data
[i
]))
242 StringC
name(data
+ start
, i
- start
);
243 syntax_
->generalSubstTable()->subst(name
);
244 arcProcessors_
.resize(arcProcessors_
.size() + 1);
245 arcProcessors_
.back().setName(name
);
249 DelegateEventHandler::pi(event
);
252 void ArcEngineImpl::endProlog(EndPrologEvent
*event
)
254 currentLocation_
= event
->location();
255 for (size_t i
= 0; i
< arcProcessors_
.size(); i
++)
256 arcProcessors_
[i
].init(*event
,
264 if (!event
->lpdPointer().isNull()) {
265 haveLinkProcess_
= 1;
266 linkProcess_
.init(event
->lpdPointer());
268 DelegateEventHandler::endProlog(event
);
271 void ArcEngineImpl::startDtd(StartDtdEvent
*event
)
274 DelegateEventHandler::startDtd(event
);
277 void ArcEngineImpl::endDtd(EndDtdEvent
*event
)
280 DelegateEventHandler::endDtd(event
);
283 void ArcEngineImpl::startLpd(StartLpdEvent
*event
)
287 DelegateEventHandler::startLpd(event
);
290 void ArcEngineImpl::endLpd(EndLpdEvent
*event
)
293 DelegateEventHandler::endLpd(event
);
296 void ArcEngineImpl::sgmlDecl(SgmlDeclEvent
*event
)
298 currentLocation_
= event
->location();
299 sd_
= event
->sdPointer();
300 syntax_
= event
->instanceSyntaxPointer();
301 arcBase_
= sd_
->execToInternal("ArcBase");
302 syntax_
->generalSubstTable()->subst(arcBase_
);
303 is10744_
= sd_
->execToInternal("IS10744");
305 for (size_t i
= 0; i
< appinfo_
.size(); i
++)
306 if (syntax_
->isS(appinfo_
[i
]))
309 if (i
+ 7 > appinfo_
.size())
311 StringC
tem(appinfo_
.data() + i
, 7);
312 syntax_
->generalSubstTable()->subst(tem
);
313 if (tem
== arcBase_
) {
314 if (i
+ 7 == appinfo_
.size() || syntax_
->isS(appinfo_
[i
+ 7]))
316 if (appinfo_
[i
+ 7] == sd_
->execToInternal('=')) {
318 for (size_t j
= i
+ 7; j
< appinfo_
.size(); j
++) {
319 if (syntax_
->isS(appinfo_
[j
]))
321 arcBase_
+= appinfo_
[j
];
323 // Allow quotes around replacement name.
324 if (arcBase_
.size() > 2
325 && (arcBase_
[0] == sd_
->execToInternal('"')
326 || arcBase_
[0] == sd_
->execToInternal('\''))
327 && arcBase_
[arcBase_
.size() - 1] == arcBase_
[0]) {
328 for (size_t j
= 0; j
< arcBase_
.size() - 2; j
++)
329 arcBase_
[j
] = arcBase_
[j
+ 1];
330 arcBase_
.resize(arcBase_
.size() - 2);
332 syntax_
->generalSubstTable()->subst(arcBase_
);
338 DelegateEventHandler::sgmlDecl(event
);
341 void ArcEngineImpl::startElement(StartElementEvent
*event
)
343 if (gatheringContent_
) {
345 DelegateEventHandler::startElement(event
);
348 currentLocation_
= event
->location();
349 const Text
*contentP
;
352 start
= startAgain_
- 1;
353 contentP
= &content_
;
359 if (haveLinkProcess_
) {
360 const ResultElementSpec
*resultElementSpec
;
361 linkProcess_
.startElement(event
->elementType(),
364 *this, // Messenger &
371 for (size_t i
= start
; i
< arcProcessors_
.size(); i
++) {
372 if (arcProcessors_
[i
].valid()) {
373 if (!arcProcessors_
[i
].processStartElement(*event
,
377 ASSERT(contentP
== 0);
379 gatheringContent_
= 1;
380 delegateTo_
= &eventQueue_
;
381 DelegateEventHandler::startElement(event
);
388 DelegateEventHandler::startElement(event
);
391 void ArcEngineImpl::data(DataEvent
*event
)
393 const Entity
*entity
= event
->entity();
394 if (gatheringContent_
) {
396 content_
.addCdata(entity
->asInternalEntity(),
397 event
->location().origin());
399 // Do attribute value literal interpretation.
400 Location
loc(event
->location());
401 for (size_t i
= 0; i
< event
->dataLength(); i
++, loc
+= 1) {
402 Char ch
= event
->data()[i
];
403 if (syntax_
->isS(ch
) && ch
!= syntax_
->space()) {
404 if (ch
== syntax_
->standardFunction(Syntax::fRS
))
405 content_
.ignoreChar(ch
, loc
);
407 content_
.addChar(syntax_
->space(),
408 Location(new ReplacementOrigin(loc
, ch
), 0));
411 content_
.addChar(ch
, loc
);
416 currentLocation_
= event
->location();
417 for (size_t i
= 0; i
< arcProcessors_
.size(); i
++) {
418 if (arcProcessors_
[i
].valid() && arcProcessors_
[i
].processData()) {
420 arcProcessors_
[i
].docHandler()
421 .data(new (alloc_
) CdataEntityEvent(entity
->asInternalEntity(),
422 event
->location().origin()));
424 arcProcessors_
[i
].docHandler()
425 .data(new (alloc_
) ImmediateDataEvent(event
->type(),
433 DelegateEventHandler::data(event
);
436 void ArcEngineImpl::sdataEntity(SdataEntityEvent
*event
)
438 if (gatheringContent_
) {
439 content_
.addSdata(event
->entity()->asInternalEntity(),
440 event
->location().origin());
444 currentLocation_
= event
->location();
445 for (size_t i
= 0; i
< arcProcessors_
.size(); i
++) {
446 if (arcProcessors_
[i
].valid() && arcProcessors_
[i
].processData()) {
447 const Entity
*entity
= event
->entity();
448 arcProcessors_
[i
].docHandler()
449 .sdataEntity(new (alloc_
)
450 SdataEntityEvent(entity
->asInternalEntity(),
451 event
->location().origin()));
455 DelegateEventHandler::sdataEntity(event
);
458 void ArcEngineImpl::externalDataEntity(ExternalDataEntityEvent
*event
)
460 if (!gatheringContent_
) {
461 currentLocation_
= event
->location();
462 for (size_t i
= 0; i
< arcProcessors_
.size(); i
++) {
463 if (arcProcessors_
[i
].valid()
464 && arcProcessors_
[i
].processData()) {
465 ConstPtr
<Entity
> entity
466 = arcProcessors_
[i
].dtdPointer()
467 ->lookupEntity(0, event
->entity()->name());
468 if (!entity
.isNull()) {
469 ConstPtr
<EntityOrigin
> oldOrigin
= event
->entityOrigin();
470 Owner
<Markup
> markup
;
471 if (oldOrigin
->markup())
472 markup
= new Markup(*oldOrigin
->markup());
473 ConstPtr
<EntityOrigin
> newOrigin
474 = EntityOrigin::make(entity
,
476 oldOrigin
->refLength(),
478 arcProcessors_
[i
].docHandler()
479 .externalDataEntity(new (alloc_
)
480 ExternalDataEntityEvent(entity
->asExternalDataEntity(),
483 // otherwise entity is not architectural
487 DelegateEventHandler::externalDataEntity(event
);
490 void ArcEngineImpl::endElement(EndElementEvent
*event
)
492 while (gatheringContent_
) {
493 if (--gatheringContent_
> 0) {
494 DelegateEventHandler::endElement(event
);
497 delegateTo_
= delegateHandler();
498 // Clear out eventQueue_ in case handling the events
499 // causes events to be queued again.
501 tem
.swap(eventQueue_
);
503 tem
.get()->handle(*this);
505 currentLocation_
= event
->location();
506 for (size_t i
= 0; i
< arcProcessors_
.size(); i
++)
507 if (arcProcessors_
[i
].valid())
508 arcProcessors_
[i
].processEndElement(*event
, alloc_
);
509 DelegateEventHandler::endElement(event
);
510 if (haveLinkProcess_
)
511 linkProcess_
.endElement();
514 void ArcEngineImpl::uselink(UselinkEvent
*event
)
516 if (!gatheringContent_
)
517 linkProcess_
.uselink(event
->linkSet(),
519 event
->lpd().pointer());
520 DelegateEventHandler::uselink(event
);
523 void ArcEngineImpl::dispatchMessage(const Message
&msg
)
525 mgr_
->dispatchMessage(msg
);
528 void ArcEngineImpl::dispatchMessage(Message
&msg
)
530 mgr_
->dispatchMessage(msg
);
533 void ArcEngineImpl::initMessage(Message
&msg
)
535 mgr_
->initMessage(msg
);
536 msg
.loc
= currentLocation_
;
539 ArcProcessor::ArcProcessor()
540 : errorIdref_(1), docHandler_(0), arcAuto_(1),
545 void ArcProcessor::setName(const StringC
&name
)
550 const Syntax
&ArcProcessor::attributeSyntax() const
555 ConstPtr
<Notation
> ArcProcessor::getAttributeNotation(const StringC
&name
,
558 if (!metaDtd_
.isNull())
559 return metaDtd_
->lookupNotation(name
);
563 ConstPtr
<Entity
> ArcProcessor::getAttributeEntity(const StringC
&name
,
566 // FIXME What about default entity
567 if (!metaDtd_
.isNull())
568 return metaDtd_
->lookupEntity(0, name
);
572 void ArcProcessor::noteCurrentAttribute(size_t i
, AttributeValue
*value
)
575 currentAttributes_
[i
] = value
;
578 ConstPtr
<AttributeValue
> ArcProcessor::getCurrentAttribute(size_t i
) const
580 return currentAttributes_
[i
];
583 // This code is the same as in the main parser.
584 // Once handling of ID/IDREF in architectures has been clarified.
585 // Maybe factor out into AttributeContext.
587 Boolean
ArcProcessor::defineId(const StringC
&str
, const Location
&loc
,
592 Id
*id
= lookupCreateId(str
);
594 prevLoc
= id
->defLocation();
601 void ArcProcessor::noteIdref(const StringC
&str
, const Location
&loc
)
603 if (!valid_
|| !errorIdref_
)
605 Id
*id
= lookupCreateId(str
);
607 id
->addPendingRef(loc
);
610 Id
*ArcProcessor::lookupCreateId(const StringC
&name
)
612 Id
*id
= idTable_
.lookup(name
);
620 void ArcProcessor::checkIdrefs()
622 NamedTableIter
<Id
> iter(idTable_
);
624 while ((id
= iter
.next()) != 0) {
625 for (size_t i
= 0; i
< id
->pendingRefs().size(); i
++) {
626 Messenger::setNextLocation(id
->pendingRefs()[i
]);
627 message(ArcEngineMessages::missingId
, StringMessageArg(id
->name()));
632 void ArcProcessor::init(const EndPrologEvent
&event
,
633 const ConstPtr
<Sd
> &sd
,
634 const ConstPtr
<Syntax
> &syntax
,
635 const SgmlParser
*parentParser
,
637 const Vector
<StringC
> &superName
,
638 ArcDirector
&director
,
639 const volatile sig_atomic_t *cancelPtr
)
641 director_
= &director
;
647 docDtd_
= event
.dtdPointer();
648 metaSyntax_
= docSyntax_
;
649 mayDefaultAttribute_
= 1;
650 docSyntax_
->generalSubstTable()->subst(name_
);
651 Vector
<StringC
> docName(superName
);
652 docName
.push_back(name_
);
653 ConstPtr
<Notation
> notation
;
654 notation
= docDtd_
->lookupNotation(name_
);
655 if (!notation
.isNull()) {
656 ConstPtr
<AttributeDefinitionList
> notAttDef
= notation
->attributeDef();
657 attributeList_
.init(notAttDef
);
658 attributeList_
.finish(*this);
659 supportAttributes(attributeList_
);
662 message(ArcEngineMessages::noArcNotation
, StringMessageArg(name_
));
663 ArcEngineImpl
*engine
664 = new ArcEngineImpl(*mgr
, parentParser
, director
, cancelPtr
,
667 docSyntax_
->generalSubstTable());
668 docHandler_
= engine
;
669 ownEventHandler_
= engine
;
670 if (supportAtts_
[rArcDocF
].size() == 0)
671 supportAtts_
[rArcDocF
] = name_
;
672 if (supportAtts_
[rArcFormA
].size() == 0)
673 supportAtts_
[rArcFormA
] = name_
;
674 rniContent_
= docSyntax_
->delimGeneral(Syntax::dRNI
);
675 rniContent_
+= sd
->execToInternal("CONTENT");
676 rniDefault_
= docSyntax_
->delimGeneral(Syntax::dRNI
);
677 rniDefault_
+= docSyntax_
->reservedName(Syntax::rDEFAULT
);
678 rniArcCont_
= metaSyntax_
->delimGeneral(Syntax::dRNI
);
679 rniArcCont_
+= sd
->execToInternal("ARCCONT");
680 ConstPtr
<Entity
> dtdent
= makeDtdEntity(notation
.pointer());
683 StringC sysid
= dtdent
->asExternalEntity()->externalId().effectiveSystemId();
684 if (sysid
.size() == 0
685 && !parentParser
->entityCatalog().lookup(*dtdent
,
687 sd
->internalCharset(),
690 message(ArcEngineMessages::arcGenerateSystemId
,
691 StringMessageArg(name_
));
694 docHandler_
->sgmlDecl(new SgmlDeclEvent(sd
, syntax
));
695 docHandler_
->startDtd(new StartDtdEvent(dtdent
->name(),
700 SgmlParser::Params params
;
701 params
.entityType
= SgmlParser::Params::dtd
;
702 params
.sysid
= sysid
;
703 params
.parent
= parentParser
;
704 ParserOptions options
= parentParser
->options();
705 errorIdref_
= options
.errorIdref
;
706 options
.errorAfdr
= 0;
707 options
.includes
= arcOpts_
;
708 params
.options
= &options
;
710 if (metaSyntax_
->reservedName(Syntax::rALL
).size() == 0) {
711 Ptr
<Syntax
> tem(new Syntax(*metaSyntax_
));
712 tem
->setName(Syntax::rALL
, docSd_
->execToInternal("ALL"));
715 params
.prologSyntax
= metaSyntax_
;
716 params
.instanceSyntax
= metaSyntax_
;
717 params
.doctypeName
= dtdent
->name();
718 SgmlParser
parser(params
);
719 parser
.parseAll(*docHandler_
, cancelPtr
);
720 Ptr
<Dtd
> baseDtd
= parser
.baseDtd();
722 || baseDtd
->documentElementType()->definition()->undefined())
725 metaMapCache_
.resize(docDtd_
->nElementTypeIndex());
726 mungeMetaDtd(*baseDtd
, *docDtd_
);
727 docHandler_
->endDtd(new EndDtdEvent(metaDtd_
, event
.location(), 0));
728 startContent(*metaDtd_
);
729 currentAttributes_
.resize(metaDtd_
->nCurrentAttribute());
731 docHandler_
->endProlog(new EndPrologEvent(metaDtd_
, event
.location()));
732 if (engine
->nBases() == 0)
733 docHandler_
= engine
->delegateHandler();
736 void ArcProcessor::mungeMetaDtd(Dtd
&metaDtd
, const Dtd
&docDtd
)
738 if (supportAtts_
[rArcDataF
].size() > 0
739 && metaDtd
.lookupNotation(supportAtts_
[rArcDataF
]).isNull()) {
740 Messenger::message(ArcEngineMessages::noArcDataF
,
741 StringMessageArg(supportAtts_
[rArcDataF
]));
742 metaDtd
.insertNotation(new Notation(supportAtts_
[rArcDataF
],
743 metaDtd
.namePointer(),
746 // FIXME check for ArcAutoF
747 Dtd::ConstEntityIter
iter(docDtd
.generalEntityIter());
749 ConstPtr
<Entity
> ent
= iter
.next();
752 Ptr
<Entity
> copy(ent
->copy());
753 if (!copy
->asExternalDataEntity()
754 || mungeDataEntity(*(ExternalDataEntity
*)copy
.pointer()))
755 metaDtd
.insertEntity(copy
, 1);
759 Boolean
ArcProcessor::mungeDataEntity(ExternalDataEntity
&entity
)
761 const MetaMap
&map
= buildMetaMap(0,
769 const Notation
*notation
= (const Notation
*)map
.attributed
;
770 ConstPtr
<AttributeValue
> arcContent
;
771 if (mapAttributes(entity
.attributes(), 0, 0, atts
, arcContent
, map
)) {
772 // FIXME check arcContent
773 entity
.setNotation((Notation
*)notation
, atts
);
776 // FIXME error tried to use #CONTENT
780 ConstPtr
<Entity
> ArcProcessor::makeDtdEntity(const Notation
*)
782 if (!supportAtts_
[rArcDTD
].size()) {
783 mgr_
->message(ArcEngineMessages::noArcDTDAtt
);
786 ConstPtr
<Entity
> entity
= docDtd_
->lookupEntity(arcDtdIsParam_
,
787 supportAtts_
[rArcDTD
]);
788 if (entity
.isNull()) {
789 mgr_
->message(arcDtdIsParam_
790 ? ArcEngineMessages::arcDtdNotDeclaredParameter
791 : ArcEngineMessages::arcDtdNotDeclaredParameter
,
792 StringMessageArg(supportAtts_
[rArcDTD
]));
795 if (!entity
->asExternalEntity()) {
796 mgr_
->message(ArcEngineMessages::arcDtdNotExternal
,
797 StringMessageArg(supportAtts_
[rArcDTD
]));
800 ExternalId
externalId(entity
->asExternalEntity()->externalId());
802 // Use the public identifier of the notation to find the meta-DTD.
803 if (externalId
.effectiveSystemId().size() == 0 && notation
) {
804 if (notation
->externalId().effectiveSystemId().size()) {
805 StringC
tem(notation
->externalId().effectiveSystemId());
806 externalId
.setEffectiveSystem(tem
);
808 else if (!externalId
.publicId()) {
809 const PublicId
*pubid
= notation
->externalId().publicId();
810 PublicId::OwnerType ownerType
;
811 if (pubid
&& pubid
->getOwnerType(ownerType
)) {
813 unsigned textClassPos
= 2;
814 if (ownerType
!= PublicId::ISO
)
817 pubid
->getOwner(owner
);
818 textClassPos
+= owner
.size();
819 pubidText
.addChars(pubid
->string().data(),
821 pubid
->text().charLocation(0));
822 pubidText
.addChars(docSd_
->execToInternal("DTD"),
823 pubid
->text().charLocation(textClassPos
));
824 for (; textClassPos
< pubid
->string().size(); textClassPos
++)
825 if (pubid
->string()[textClassPos
] == docSyntax_
->space())
827 pubidText
.addChars(pubid
->string().data() + textClassPos
,
828 pubid
->string().size() - textClassPos
,
829 pubid
->text().charLocation(textClassPos
));
830 const MessageType1
*msg
;
831 externalId
.setPublic(pubidText
, docSd_
->internalCharset(),
832 docSyntax_
->space(), msg
);
837 return new ExternalTextEntity(supportAtts_
[rArcDocF
],
839 entity
->defLocation(),
843 void ArcProcessor::supportAttributes(const AttributeList
&atts
)
845 static const char *const s
[] = {
859 for (size_t i
= 0; i
< SIZEOF(s
); i
++) {
860 StringC
attName(docSd_
->execToInternal(s
[i
]));
861 docSyntax_
->generalSubstTable()->subst(attName
);
863 if (atts
.attributeIndex(attName
, ind
)) {
864 const AttributeValue
*value
= atts
.value(ind
);
866 const Text
*textP
= value
->text();
867 // FIXME check for empty value
869 supportAtts_
[i
] = textP
->string();
872 processArcQuant(*textP
);
875 docSyntax_
->generalSubstTable()->subst(supportAtts_
[i
]);
876 if (supportAtts_
[i
] == docSd_
->execToInternal("ARCAUTO"))
878 else if (supportAtts_
[i
] == docSd_
->execToInternal("NARCAUTO"))
881 Messenger::message(ArcEngineMessages::invalidArcAuto
,
882 StringMessageArg(supportAtts_
[i
]));
885 docSyntax_
->generalSubstTable()->subst(supportAtts_
[i
]);
886 if (supportAtts_
[i
] == docSd_
->execToInternal("ARCINDR")) {
887 Messenger::setNextLocation(textP
->charLocation(0));
888 Messenger::message(ArcEngineMessages::arcIndrNotSupported
);
890 else if (supportAtts_
[i
] != docSd_
->execToInternal("NARCINDR")) {
891 Messenger::setNextLocation(textP
->charLocation(0));
892 Messenger::message(ArcEngineMessages::invalidArcIndr
,
893 StringMessageArg(supportAtts_
[i
]));
900 docSyntax_
->generalSubstTable()->subst(supportAtts_
[i
]);
906 metaSyntax_
->generalSubstTable()->subst(supportAtts_
[i
]);
910 const StringC
&pero
= docSyntax_
->delimGeneral(Syntax::dPERO
);
911 if (supportAtts_
[i
].size() >= pero
.size()) {
912 StringC
tem(supportAtts_
[i
].data(), pero
.size());
913 docSyntax_
->generalSubstTable()->subst(tem
);
916 tem
.assign(supportAtts_
[i
].data() + pero
.size(),
917 supportAtts_
[i
].size() - pero
.size());
918 tem
.swap(supportAtts_
[i
]);
921 docSyntax_
->entitySubstTable()->subst(supportAtts_
[i
]);
929 processArcOpts(atts
);
932 void ArcProcessor::processArcOpts(const AttributeList
&atts
)
934 StringC
attName(docSd_
->execToInternal("ArcOptSA"));
935 docSyntax_
->generalSubstTable()->subst(attName
);
937 Vector
<StringC
> arcOptA
;
938 Vector
<size_t> arcOptAPos
;
939 const Text
*arcOptAText
= 0;
940 if (atts
.attributeIndex(attName
, ind
)) {
941 const AttributeValue
*value
= atts
.value(ind
);
943 arcOptAText
= value
->text();
945 split(*arcOptAText
, docSyntax_
->space(), arcOptA
, arcOptAPos
);
949 arcOptA
.push_back(docSd_
->execToInternal("ArcOpt"));
950 for (size_t i
= 0; i
< arcOptA
.size(); i
++) {
951 docSyntax_
->generalSubstTable()->subst(arcOptA
[i
]);
952 if (atts
.attributeIndex(arcOptA
[i
], ind
)) {
953 const AttributeValue
*value
= atts
.value(ind
);
955 const Text
*textP
= value
->text();
957 Vector
<StringC
> opts
;
958 Vector
<size_t> optsPos
;
959 split(*textP
, docSyntax_
->space(), opts
, optsPos
);
960 arcOpts_
.insert(arcOpts_
.begin(),
961 opts
.begin(), opts
.begin() + opts
.size());
968 void ArcProcessor::processArcQuant(const Text
&text
)
970 Ptr
<Syntax
> newMetaSyntax
;
971 Vector
<StringC
> tokens
;
972 Vector
<size_t> tokensPos
;
973 split(text
, docSyntax_
->space(), tokens
, tokensPos
);
974 for (size_t i
= 0; i
< tokens
.size(); i
++) {
975 docSyntax_
->generalSubstTable()->subst(tokens
[i
]);
976 Syntax::Quantity quantityName
;
977 if (!docSd_
->lookupQuantityName(tokens
[i
], quantityName
)) {
978 setNextLocation(text
.charLocation(tokensPos
[i
]));
979 Messenger::message(ArcEngineMessages::invalidQuantity
,
980 StringMessageArg(tokens
[i
]));
982 else if (i
+ 1 >= tokens
.size()) {
983 setNextLocation(text
.charLocation(tokensPos
[i
]));
984 Messenger::message(ArcEngineMessages::missingQuantityValue
,
985 StringMessageArg(tokens
[i
]));
989 unsigned long val
= 0;
990 if (tokens
[i
].size() > 8) {
991 setNextLocation(text
.charLocation(tokensPos
[i
] + 8));
992 Messenger::message(ArcEngineMessages::quantityValueTooLong
,
993 StringMessageArg(tokens
[i
]));
996 for (size_t j
= 0; j
< tokens
[i
].size(); j
++) {
997 int weight
= docSd_
->digitWeight(tokens
[i
][j
]);
999 setNextLocation(text
.charLocation(tokensPos
[i
] + j
));
1000 Char c
= tokens
[i
][j
];
1001 Messenger::message(ArcEngineMessages::invalidDigit
,
1002 StringMessageArg(StringC(&c
, 1)));
1011 if (val
> docSyntax_
->quantity(quantityName
)) {
1012 if (newMetaSyntax
.isNull())
1013 newMetaSyntax
= new Syntax(*docSyntax_
);
1014 newMetaSyntax
->setQuantity(quantityName
, val
);
1018 if (!newMetaSyntax
.isNull())
1019 metaSyntax_
= newMetaSyntax
;
1022 Boolean
ArcProcessor::processStartElement(const StartElementEvent
&event
,
1023 const AttributeList
*linkAttributes
,
1024 const Text
*content
,
1027 unsigned suppressFlags
= (openElementFlags_
.size() > 0
1028 ? (openElementFlags_
.back() & ~isArc
)
1029 : (unsigned)condIgnoreData
);
1030 if ((suppressFlags
& suppressForm
)
1031 && (suppressFlags
& suppressSupr
)) {
1032 // Make this case efficient.
1033 openElementFlags_
.push_back(suppressFlags
);
1036 const AttributeList
&atts
= event
.attributes();
1037 const MetaMap
&map
= buildMetaMap(event
.elementType(),
1042 const ElementType
*metaType
;
1043 ConstPtr
<AttributeValue
> arcContent
;
1044 if (map
.attributed
== 0) {
1045 if (!(tagLevel() == 0
1046 && !currentElement().isFinished())) {
1047 if (!arcContent
.isNull()
1048 && (currentElement().declaredEmpty()
1049 || !currentElement().tryTransitionPcdata()))
1050 Messenger::message(ArcEngineMessages::invalidArcContent
);
1051 openElementFlags_
.push_back(map
.suppressFlags
);
1054 metaType
= metaDtd_
->documentElementType();
1055 mgr_
->message(ArcEngineMessages::documentElementNotArc
,
1056 StringMessageArg(metaType
->name()));
1057 attributeList_
.init(metaType
->attributeDef());
1058 attributeList_
.finish(*this);
1061 if (!mapAttributes(atts
, linkAttributes
, content
, attributeList_
,
1064 metaType
= (const ElementType
*)map
.attributed
;
1065 suppressFlags
= map
.suppressFlags
;
1067 StartElementEvent
*genEvent
1068 = new (alloc
) StartElementEvent(metaType
,
1073 if (metaType
->definition()->undefined())
1074 Messenger::message(ArcEngineMessages::undefinedElement
,
1075 StringMessageArg(metaType
->name()));
1076 else if (elementIsExcluded(metaType
))
1077 Messenger::message(ArcEngineMessages::elementExcluded
,
1078 StringMessageArg(metaType
->name()));
1079 else if (elementIsIncluded(metaType
))
1080 genEvent
->setIncluded();
1081 else if (!currentElement().tryTransition(metaType
))
1082 Messenger::message(ArcEngineMessages::invalidElement
,
1083 StringMessageArg(metaType
->name()));
1085 pushElement(new (alloc
) OpenElement(metaType
,
1087 genEvent
->included(),
1090 docHandler_
->startElement(genEvent
);
1091 if (attributeList_
.conref())
1092 currentElement().setConref();
1093 if (!arcContent
.isNull() && arcContent
->text() != 0) {
1094 if (currentElement().declaredEmpty()
1095 || !currentElement().tryTransitionPcdata())
1096 Messenger::message(ArcEngineMessages::invalidArcContent
);
1098 emitArcContent(*arcContent
->text(), docHandler(), alloc
);
1099 suppressFlags
|= (suppressForm
|suppressSupr
|ignoreData
);
1101 suppressFlags
&= ~recoverData
;
1102 openElementFlags_
.push_back(suppressFlags
| isArc
);
1106 void ArcProcessor::emitArcContent(const Text
&text
,
1107 EventHandler
&handler
,
1110 TextIter
iter(text
);
1111 TextItem::Type type
;
1114 const Location
*loc
;
1115 while (iter
.next(type
, s
, n
, loc
))
1117 case TextItem::data
:
1118 case TextItem::cdata
:
1119 // +1 because first dataEvent is the non-architectural data.
1120 if (type
== TextItem::data
)
1121 handler
.data(new (alloc
) ImmediateDataEvent(Event::characterData
,
1128 handler
.data(new (alloc
)
1129 CdataEntityEvent(loc
->origin()->asEntityOrigin()
1130 ->entity()->asInternalEntity(),
1133 case TextItem::sdata
:
1135 handler
.sdataEntity(new (alloc
)
1136 SdataEntityEvent(loc
->origin()->asEntityOrigin()
1137 ->entity()->asInternalEntity(),
1145 Boolean
ArcProcessor::processData()
1147 if (openElementFlags_
.size() > 0
1148 && (openElementFlags_
.back() & ignoreData
))
1150 if (!currentElement().declaredEmpty()
1151 && currentElement().tryTransitionPcdata())
1153 else if (openElementFlags_
.size() > 0
1154 && (openElementFlags_
.back() & condIgnoreData
))
1157 // Only give this error once per element
1158 if (openElementFlags_
.size() > 0) {
1159 if (openElementFlags_
.back() & recoverData
)
1161 openElementFlags_
.back() |= recoverData
;
1163 Messenger::message(ArcEngineMessages::invalidData
);
1168 Boolean
ArcProcessor::mapAttributes(const AttributeList
&from
,
1169 const AttributeList
*fromLink
,
1170 const Text
*content
,
1172 ConstPtr
<AttributeValue
> &arcContent
,
1176 to
.init(map
.attributed
->attributeDef());
1177 for (size_t i
= 0; i
< map
.attMapFrom
.size(); i
++) {
1178 unsigned fromIndex
= map
.attMapFrom
[i
];
1179 const AttributeList
*fromList
= &from
;
1180 if (fromIndex
!= contentPseudoAtt
&& fromIndex
>= fromList
->size()) {
1181 fromList
= fromLink
;
1182 fromIndex
-= from
.size();
1184 if (map
.attMapTo
[i
] == contentPseudoAtt
) {
1185 if (fromIndex
!= contentPseudoAtt
)
1186 arcContent
= fromList
->valuePointer(fromIndex
);
1189 const Text
*fromText
= 0;
1190 Boolean fromTextTokenized
= 0;
1191 if (map
.attMapFrom
[i
] == contentPseudoAtt
) {
1197 const AttributeValue
*value
= fromList
->value(fromIndex
);
1199 fromText
= value
->text();
1200 fromTextTokenized
= fromList
->tokenized(fromIndex
);
1202 && fromList
== &from
1203 && !from
.specified(fromIndex
)
1204 && (map
.attributed
->attributeDef()->def(map
.attMapTo
[i
])
1205 ->missingValueWouldMatch(*fromText
, *this)))
1210 unsigned specLength
= 0;
1212 if (!fromTextTokenized
&& to
.tokenized(map
.attMapTo
[i
]))
1213 fromText
->tokenize(docSyntax_
->space(), tem
);
1216 to
.setSpec(map
.attMapTo
[i
], *this);
1217 to
.setValue(map
.attMapTo
[i
], tem
, *this, specLength
);
1226 const ArcProcessor::MetaMap
&
1227 ArcProcessor::buildMetaMap(const ElementType
*docElementType
,
1228 const Notation
*notation
,
1229 const AttributeList
&atts
,
1230 const AttributeList
*linkAtts
,
1231 unsigned suppressFlags
)
1234 const Attributed
*attributed
= docElementType
;
1235 const StringC
*nameP
;
1237 attributed
= notation
;
1239 nameP
= ¬ation
->name();
1243 nameP
= &docElementType
->name();
1245 // Try to use cached entry.
1246 Boolean inhibitCache
= 0;
1248 if (isNotation
|| docElementType
->definition()->undefined()) {
1250 cacheIndex
= (unsigned)-1;
1253 cacheIndex
= docElementType
->index();
1254 const MetaMapCache
*cache
= metaMapCache_
[cacheIndex
].pointer();
1256 && cache
->suppressFlags
== suppressFlags
1257 && cache
->linkAtts
== linkAtts
) {
1258 for (int i
= 0;; i
++) {
1259 if (i
== MetaMapCache::nNoSpec
)
1261 unsigned attIndex
= cache
->noSpec
[i
];
1262 if (attIndex
!= invalidAtt
&& atts
.specified(attIndex
))
1267 // no valid cached MetaMap
1268 // Handle suppression.
1269 unsigned oldSuppressFlags
= suppressFlags
;
1270 unsigned newSuppressFlags
= suppressFlags
;
1271 unsigned arcSuprIndex
;
1273 considerSupr(atts
, linkAtts
, suppressFlags
, newSuppressFlags
, inhibitCache
,
1276 arcSuprIndex
= invalidAtt
;
1278 unsigned arcIgnDIndex
;
1280 considerIgnD(atts
, linkAtts
, suppressFlags
, newSuppressFlags
, inhibitCache
,
1283 arcIgnDIndex
= invalidAtt
;
1285 unsigned arcFormIndex
;
1286 const Attributed
*metaAttributed
1287 = considerForm(atts
, linkAtts
, *nameP
, isNotation
,
1288 suppressFlags
, newSuppressFlags
,
1289 inhibitCache
, arcFormIndex
);
1290 // See if there's a renamer that will inhibit cacheing.
1291 #pragma "%Z%%M% %I% %E% SMI"
1292 unsigned arcNamerIndex
;
1293 const Text
*namerText
;
1295 namerText
= considerNamer(atts
, inhibitCache
, arcNamerIndex
);
1297 arcNamerIndex
= invalidAtt
;
1302 noCacheMetaMap_
.clear();
1303 mapP
= &noCacheMetaMap_
;
1306 MetaMapCache
*cache
= metaMapCache_
[cacheIndex
].pointer();
1310 cache
= new MetaMapCache
;
1311 metaMapCache_
[cacheIndex
] = cache
;
1313 cache
->noSpec
[0] = arcFormIndex
;
1314 cache
->noSpec
[1] = arcNamerIndex
;
1315 cache
->noSpec
[2] = arcSuprIndex
;
1316 cache
->noSpec
[3] = arcIgnDIndex
;
1317 cache
->suppressFlags
= oldSuppressFlags
;
1318 cache
->linkAtts
= linkAtts
;
1321 mapP
->attributed
= metaAttributed
;
1322 mapP
->suppressFlags
= newSuppressFlags
;
1323 // Build the attribute map.
1324 if (metaAttributed
) {
1325 Vector
<PackedBoolean
> renamed
;
1326 ConstPtr
<AttributeDefinitionList
> metaAttDef
1327 = metaAttributed
->attributeDef();
1328 if (!metaAttDef
.isNull())
1329 renamed
.assign(metaAttDef
->size(), PackedBoolean(0));
1333 const Text
*linkNamerText
= considerNamer(*linkAtts
, specified
, index
);
1335 buildAttributeMapRename(*mapP
, *linkNamerText
, atts
, linkAtts
, renamed
);
1338 buildAttributeMapRename(*mapP
, *namerText
, atts
, 0, renamed
);
1339 buildAttributeMapRest(*mapP
, atts
, linkAtts
, renamed
);
1344 void ArcProcessor::considerSupr(const AttributeList
&atts
,
1345 const AttributeList
*linkAtts
,
1346 unsigned &thisSuppressFlags
,
1347 unsigned &newSuppressFlags
,
1348 Boolean
&inhibitCache
,
1349 unsigned &arcSuprIndex
)
1351 arcSuprIndex
= invalidAtt
;
1352 if (thisSuppressFlags
& suppressSupr
)
1354 if (!supportAtts_
[rArcSuprA
].size())
1356 const AttributeValue
*val
;
1358 if (linkAtts
&& linkAtts
->attributeIndex(supportAtts_
[rArcSuprA
], tem
))
1359 val
= linkAtts
->value(tem
);
1360 else if (atts
.attributeIndex(supportAtts_
[rArcSuprA
], arcSuprIndex
)) {
1361 if (atts
.current(arcSuprIndex
) || atts
.specified(arcSuprIndex
))
1363 val
= atts
.value(arcSuprIndex
);
1369 const Text
*textP
= val
->text();
1372 StringC token
= textP
->string();
1373 // FIXME trim spaces
1374 docSyntax_
->generalSubstTable()->subst(token
);
1375 // sArcForm suppress processing for all elements except
1376 // those that have a non-implied ArcSupr attribute.
1377 thisSuppressFlags
&= ~suppressForm
;
1378 newSuppressFlags
&= ~(suppressForm
|suppressSupr
);
1379 if (matchName(token
, "sArcForm"))
1380 newSuppressFlags
|= suppressForm
;
1382 // I don't think this is useful
1383 else if (matchName(token
, "sArcSupr"))
1384 newSuppressFlags
|= suppressSupr
;
1386 else if (matchName(token
, "sArcAll"))
1387 newSuppressFlags
|= (suppressSupr
|suppressForm
);
1388 else if (!matchName(token
, "sArcNone")) {
1389 Messenger::setNextLocation(textP
->charLocation(0));
1390 Messenger::message(ArcEngineMessages::invalidSuppress
,
1391 StringMessageArg(token
));
1395 void ArcProcessor::considerIgnD(const AttributeList
&atts
,
1396 const AttributeList
*linkAtts
,
1397 unsigned thisSuppressFlags
,
1398 unsigned &newSuppressFlags
,
1399 Boolean
&inhibitCache
,
1400 unsigned &arcIgnDIndex
)
1402 arcIgnDIndex
= invalidAtt
;
1403 if (thisSuppressFlags
& suppressSupr
)
1405 if (!supportAtts_
[rArcIgnDA
].size())
1407 const AttributeValue
*val
;
1409 if (linkAtts
&& linkAtts
->attributeIndex(supportAtts_
[rArcIgnDA
], tem
))
1410 val
= linkAtts
->value(tem
);
1411 else if (atts
.attributeIndex(supportAtts_
[rArcIgnDA
], arcIgnDIndex
)) {
1412 if (atts
.current(arcIgnDIndex
) || atts
.specified(arcIgnDIndex
))
1414 val
= atts
.value(arcIgnDIndex
);
1420 const Text
*textP
= val
->text();
1423 StringC token
= textP
->string();
1424 // FIXME trim spaces
1425 docSyntax_
->generalSubstTable()->subst(token
);
1426 newSuppressFlags
&= ~(ignoreData
|condIgnoreData
);
1427 if (matchName(token
, "ArcIgnD"))
1428 newSuppressFlags
|= ignoreData
;
1429 else if (matchName(token
, "cArcIgnD"))
1430 newSuppressFlags
|= condIgnoreData
;
1431 else if (!matchName(token
, "nArcIgnD")) {
1432 Messenger::setNextLocation(textP
->charLocation(0));
1433 Messenger::message(ArcEngineMessages::invalidIgnD
,
1434 StringMessageArg(token
));
1439 ArcProcessor::considerForm(const AttributeList
&atts
,
1440 const AttributeList
*linkAtts
,
1441 const StringC
&name
,
1443 unsigned thisSuppressFlags
,
1444 unsigned &newSuppressFlags
,
1445 Boolean
&inhibitCache
,
1446 unsigned &arcFormIndex
)
1448 arcFormIndex
= invalidAtt
;
1449 if ((thisSuppressFlags
& suppressForm
)
1450 && (supportAtts_
[rArcSuprF
].size() == 0
1451 || (thisSuppressFlags
& suppressSupr
)
1455 const AttributeValue
*val
;
1456 if (linkAtts
&& linkAtts
->attributeIndex(supportAtts_
[rArcFormA
], tem
))
1457 val
= linkAtts
->value(tem
);
1458 else if (atts
.attributeIndex(supportAtts_
[rArcFormA
], arcFormIndex
)) {
1459 if (atts
.current(arcFormIndex
) || atts
.specified(arcFormIndex
))
1461 val
= atts
.value(arcFormIndex
);
1464 return autoForm(atts
, name
, isNotation
,
1465 thisSuppressFlags
, newSuppressFlags
,
1466 inhibitCache
, arcFormIndex
);
1470 const Text
*textP
= val
->text();
1474 metaName
= textP
->string();
1475 // FIXME should trim leading and trailing spaces
1476 metaSyntax_
->generalSubstTable()->subst(metaName
);
1478 const Attributed
*metaAttributed
= metaDtd_
->lookupElementType(metaName
);
1479 if (!metaAttributed
) // CONSTDTD
1480 metaAttributed
= lookupCreateUndefinedElement(metaName
, Location(), *metaDtd_
);
1481 if (metaName
== supportAtts_
[rArcSuprF
]) {
1482 newSuppressFlags
|= suppressForm
;
1483 return metaAttributed
;
1485 if (thisSuppressFlags
& suppressForm
)
1487 return metaAttributed
;
1490 return metaDtd_
->lookupNotation(metaName
).pointer();
1494 ArcProcessor::autoForm(const AttributeList
&atts
,
1495 const StringC
&name
,
1497 unsigned thisSuppressFlags
,
1498 unsigned &newSuppressFlags
,
1499 Boolean
&inhibitCache
,
1503 const Attributed
*metaAttributed
;
1504 if (openElementFlags_
.size() == 0) {
1505 metaAttributed
= metaDtd_
->documentElementType();
1511 metaAttributed
= metaDtd_
->lookupElementType(name
);
1513 && supportAtts_
[rArcBridF
].size() > 0
1514 && atts
.idIndex(idIndex
)
1515 && atts
.specified(idIndex
)) {
1518 = metaDtd_
->lookupElementType(supportAtts_
[rArcBridF
]);
1522 && name
== supportAtts_
[rArcSuprF
]) {
1523 newSuppressFlags
= suppressForm
|ignoreData
;
1525 else if (thisSuppressFlags
& suppressForm
)
1527 return metaAttributed
;
1529 else if (thisSuppressFlags
& suppressForm
)
1532 const Attributed
*metaAttributed
= 0;
1534 metaAttributed
= metaDtd_
->lookupNotation(name
).pointer();
1535 if (!metaAttributed
&& supportAtts_
[rArcDataF
].size() > 0)
1537 = metaDtd_
->lookupNotation(supportAtts_
[rArcDataF
]).pointer();
1538 return metaAttributed
;
1544 ArcProcessor::considerNamer(const AttributeList
&atts
,
1545 Boolean
&inhibitCache
,
1546 unsigned &arcNamerIndex
)
1548 arcNamerIndex
= invalidAtt
;
1549 if (supportAtts_
[rArcNamrA
].size() == 0
1550 || !atts
.attributeIndex(supportAtts_
[rArcNamrA
], arcNamerIndex
))
1552 if (atts
.current(arcNamerIndex
) || atts
.specified(arcNamerIndex
))
1554 const AttributeValue
*val
= atts
.value(arcNamerIndex
);
1560 void ArcProcessor::buildAttributeMapRename(MetaMap
&map
,
1562 const AttributeList
&atts
,
1563 const AttributeList
*linkAtts
,
1564 Vector
<PackedBoolean
> &attRenamed
)
1566 Vector
<StringC
> tokens
;
1567 Vector
<size_t> tokensPos
;
1568 split(rename
, docSyntax_
->space(), tokens
, tokensPos
);
1569 ConstPtr
<AttributeDefinitionList
> metaAttDef
;
1571 metaAttDef
= map
.attributed
->attributeDef();
1572 // FIXME Should check that ARCCONT doesn't appear more than once.
1573 for (size_t i
= 0; i
< tokens
.size(); i
+= 2) {
1574 unsigned fromIndex
= invalidAtt
;
1575 unsigned toIndex
= invalidAtt
;
1576 metaSyntax_
->generalSubstTable()->subst(tokens
[i
]);
1577 if (tokens
[i
] == rniArcCont_
)
1578 toIndex
= contentPseudoAtt
;
1579 else if (metaAttDef
.isNull()
1580 || !metaAttDef
->attributeIndex(tokens
[i
], toIndex
)) {
1581 setNextLocation(rename
.charLocation(tokensPos
[i
]));
1582 Messenger::message(ArcEngineMessages::renameToInvalid
,
1583 StringMessageArg(tokens
[i
]));
1585 else if (attRenamed
[toIndex
]) {
1586 toIndex
= invalidAtt
;
1587 setNextLocation(rename
.charLocation(tokensPos
[i
]));
1588 Messenger::message(ArcEngineMessages::renameToDuplicate
,
1589 StringMessageArg(tokens
[i
]));
1591 if (i
+ 1 >= tokens
.size()) {
1592 setNextLocation(rename
.charLocation(tokensPos
[i
]));
1593 Messenger::message(ArcEngineMessages::renameMissingAttName
);
1596 docSyntax_
->generalSubstTable()->subst(tokens
[i
+ 1]);
1597 if (tokens
[i
+ 1] == rniContent_
) {
1598 fromIndex
= contentPseudoAtt
;
1600 else if (tokens
[i
+ 1] == rniDefault_
) {
1601 if (toIndex
!= contentPseudoAtt
)
1602 attRenamed
[toIndex
] = 1;
1605 && linkAtts
->attributeIndex(tokens
[i
+ 1], fromIndex
))
1606 fromIndex
+= atts
.size();
1607 else if (!atts
.attributeIndex(tokens
[i
+ 1], fromIndex
)) {
1608 setNextLocation(rename
.charLocation(tokensPos
[i
+ 1]));
1609 Messenger::message(ArcEngineMessages::renameFromInvalid
,
1610 StringMessageArg(tokens
[i
+ 1]));
1613 if (fromIndex
!= invalidAtt
&& toIndex
!= invalidAtt
) {
1614 map
.attMapFrom
.push_back(fromIndex
);
1615 map
.attMapTo
.push_back(toIndex
);
1616 if (toIndex
!= contentPseudoAtt
) {
1617 attRenamed
[toIndex
] = 1;
1618 if (metaAttDef
->def(toIndex
)->isId()
1619 && (fromIndex
>= atts
.size() || !atts
.id(fromIndex
)))
1620 Messenger::message(ArcEngineMessages::idMismatch
,
1621 StringMessageArg(metaAttDef
->def(toIndex
)
1628 void ArcProcessor::buildAttributeMapRest(MetaMap
&map
,
1629 const AttributeList
&atts
,
1630 const AttributeList
*linkAtts
,
1631 const Vector
<PackedBoolean
> &attRenamed
)
1633 ConstPtr
<AttributeDefinitionList
> metaAttDef
1634 = map
.attributed
->attributeDef();
1635 if (metaAttDef
.isNull())
1637 for (unsigned i
= 0; i
< metaAttDef
->size(); i
++)
1638 if (!attRenamed
[i
]) {
1640 if (metaAttDef
->def(i
)->isId()) {
1641 for (unsigned j
= 0; j
< atts
.size(); j
++)
1643 map
.attMapFrom
.push_back(j
);
1644 map
.attMapTo
.push_back(i
);
1648 else if (linkAtts
&& linkAtts
->attributeIndex(metaAttDef
->def(i
)->name(),
1650 map
.attMapFrom
.push_back(fromIndex
+ atts
.size());
1651 map
.attMapTo
.push_back(i
);
1653 else if (atts
.attributeIndex(metaAttDef
->def(i
)->name(), fromIndex
)) {
1654 map
.attMapFrom
.push_back(fromIndex
);
1655 map
.attMapTo
.push_back(i
);
1660 Boolean
ArcProcessor::matchName(const StringC
&name
, const char *key
)
1662 if (name
.size() != strlen(key
))
1664 StringC
tem(docSd_
->execToInternal(key
));
1665 docSyntax_
->generalSubstTable()->subst(tem
);
1669 void ArcProcessor::split(const Text
&text
,
1671 Vector
<StringC
> &tokens
,
1672 Vector
<size_t> &tokensPos
)
1674 const StringC
&str
= text
.string();
1675 for (size_t i
= 0;;) {
1676 for (; i
< str
.size() && str
[i
] == space
; i
++)
1678 if (i
>= str
.size())
1681 for (; i
< str
.size() && str
[i
] != space
; i
++)
1683 tokens
.push_back(StringC(str
.data() + start
, i
- start
));
1684 tokensPos
.push_back(start
);
1688 void ArcProcessor::processEndElement(const EndElementEvent
&event
,
1691 Boolean wasArc
= (openElementFlags_
.back() & isArc
);
1692 openElementFlags_
.resize(openElementFlags_
.size() - 1);
1694 EndElementEvent
*genEvent
1695 = new (alloc
) EndElementEvent(currentElement().type(),
1699 if (currentElement().included())
1700 genEvent
->setIncluded();
1701 docHandler_
->endElement(genEvent
);
1702 if (!currentElement().isFinished())
1703 Messenger::message(ArcEngineMessages::unfinishedElement
,
1704 StringMessageArg(currentElement().type()->name()));
1709 void ArcProcessor::dispatchMessage(Message
&msg
)
1711 mgr_
->dispatchMessage(msg
);
1714 void ArcProcessor::dispatchMessage(const Message
&msg
)
1716 mgr_
->dispatchMessage(msg
);
1719 void ArcProcessor::initMessage(Message
&msg
)
1721 mgr_
->initMessage(msg
);
1723 StringC rniPcdata
= metaSyntax_
->delimGeneral(Syntax::dRNI
);
1724 rniPcdata
+= metaSyntax_
->reservedName(Syntax::rPCDATA
);
1725 getOpenElementInfo(msg
.openElementInfo
, rniPcdata
);
1729 ArcProcessor::MetaMapCache::MetaMapCache()
1731 for (int i
= 0; i
< nNoSpec
; i
++)
1732 noSpec
[i
] = invalidAtt
;
1736 void ArcProcessor::MetaMapCache::clear()
1738 for (int i
= 0; i
< nNoSpec
; i
++)
1739 noSpec
[i
] = invalidAtt
;
1744 ArcProcessor::MetaMap::MetaMap()
1749 void ArcProcessor::MetaMap::clear()