📄 arcengine.cxx
字号:
// Copyright (c) 1996 James Clark// See the file COPYING for copying permission.#ifdef __GNUG__#pragma implementation#endif#include "splib.h"#include "ArcEngine.h"#include "ArcProcessor.h"#include "Vector.h"#include "NCVector.h"#include "IQueue.h"#include "ArcEngineMessages.h"#include "MessageArg.h"#include "ParserOptions.h"#include "SgmlParser.h"#include "Allocator.h"#include "LinkProcess.h"#include "macros.h"#ifdef SP_NAMESPACEnamespace SP_NAMESPACE {#endifstatic const size_t sizes[] = { sizeof(StartElementEvent), sizeof(EndElementEvent), sizeof(ImmediateDataEvent), sizeof(SdataEntityEvent), sizeof(EndPrologEvent), sizeof(CdataEntityEvent), sizeof(SdataEntityEvent), sizeof(ExternalDataEntityEvent), sizeof(OpenElement)};staticsize_t maxSize(const size_t *v, size_t n){ size_t max = 0; for (size_t i = 0; i < n; i++) { if (v[i] > max) max = v[i]; } return max;}const unsigned invalidAtt = unsigned(-1);const unsigned contentPseudoAtt = unsigned(-2);class DelegateEventHandler : public EventHandler {public:#define EVENT(C, f) void f(C *ev) { delegateTo_->f(ev); }#include "events.h"#undef EVENTprotected: EventHandler *delegateTo_;};class QueueEventHandler : public EventHandler, public IQueue<Event> {public:#define EVENT(C, f) void f(C *ev) { ev->copyData(); append(ev); }#include "events.h"#undef EVENT};// This just passes through messages.class NullEventHandler : public EventHandler {public: NullEventHandler(Messenger &mgr) : mgr_(&mgr) { } void message(MessageEvent *event) { mgr_->dispatchMessage(event->message()); delete event; }private: Messenger *mgr_;};class ArcEngineImpl : public DelegateEventHandler, private Messenger {public: ArcEngineImpl(Messenger &mgr, const SgmlParser *parser, ArcDirector &director, const volatile sig_atomic_t *cancelPtr, const Notation *, const Vector<StringC> &name, const SubstTable<Char> *table); ~ArcEngineImpl(); void sgmlDecl(SgmlDeclEvent *); void appinfo(AppinfoEvent *); void startElement(StartElementEvent *); void endElement(EndElementEvent *); void data(DataEvent *); void sdataEntity(SdataEntityEvent *); void externalDataEntity(ExternalDataEntityEvent *); void pi(PiEvent *); void endProlog(EndPrologEvent *); void startDtd(StartDtdEvent *); void endDtd(EndDtdEvent *); void startLpd(StartLpdEvent *); void endLpd(EndLpdEvent *); void uselink(UselinkEvent *); size_t nBases() const { return arcProcessors_.size(); } EventHandler *delegateHandler() { return eventHandler_; }private: void dispatchMessage(const Message &); void dispatchMessage(Message &); void initMessage(Message &); EventHandler *eventHandler_; NCVector<ArcProcessor> arcProcessors_; ConstPtr<Sd> sd_; ConstPtr<Syntax> syntax_; StringC arcBase_; StringC is10744_; int stage_; QueueEventHandler eventQueue_; NullEventHandler nullHandler_; const SgmlParser *parser_; Location currentLocation_; unsigned gatheringContent_; Text content_; unsigned startAgain_; Allocator alloc_; StringC appinfo_; const AttributeList *linkAttributes_; LinkProcess linkProcess_; Boolean haveLinkProcess_; Vector<StringC> docName_; ArcDirector *director_; Messenger *mgr_; const volatile sig_atomic_t *cancelPtr_;};void ArcEngine::parseAll(SgmlParser &parser, Messenger &mgr, ArcDirector &director, const volatile sig_atomic_t *cancelPtr){ ArcEngineImpl wrap(mgr, &parser, director, cancelPtr, 0, Vector<StringC>(), 0); parser.parseAll(wrap, cancelPtr);}EventHandler *SelectOneArcDirector::arcEventHandler(const Notation *, const Vector<StringC> &name, const SubstTable<Char> *table){ if (name.size() != select_.size()) return 0; for (size_t i = 0; i < name.size(); i++) { StringC tem(select_[i]); table->subst(tem); if (name[i] != tem) return 0; } return eh_;}void SelectOneArcDirector::dispatchMessage(const Message &msg){ eh_->message(new MessageEvent(msg));}void SelectOneArcDirector::dispatchMessage(Message &msg){ eh_->message(new MessageEvent(msg));}ArcEngineImpl::ArcEngineImpl(Messenger &mgr, const SgmlParser *parser, ArcDirector &director, const volatile sig_atomic_t *cancelPtr, const Notation *notation, const Vector<StringC> &docName, const SubstTable<Char> *table): director_(&director), mgr_(&mgr), cancelPtr_(cancelPtr), parser_(parser), stage_(0), gatheringContent_(0), startAgain_(0), haveLinkProcess_(0), alloc_(maxSize(sizes, SIZEOF(sizes)), 50), nullHandler_(mgr), docName_(docName){ eventHandler_ = director.arcEventHandler(notation, docName, table); if (!eventHandler_) eventHandler_ = &nullHandler_; delegateTo_ = eventHandler_;}ArcEngineImpl::~ArcEngineImpl(){ for (size_t i = 0; i < arcProcessors_.size(); i++) if (arcProcessors_[i].valid()) arcProcessors_[i].checkIdrefs();}void ArcEngineImpl::appinfo(AppinfoEvent *event){ const StringC *str; if (event->literal(str)) appinfo_ = *str; DelegateEventHandler::appinfo(event);}void ArcEngineImpl::pi(PiEvent *event){ currentLocation_ = event->location(); if (stage_ == 1 && arcBase_.size() && event->dataLength() > is10744_.size() + 1) { Boolean match = 1; size_t i = 0; for (size_t j = 0; j < is10744_.size() && match; i++, j++) if ((*syntax_->generalSubstTable())[event->data()[i]] != is10744_[j]) match = 0; if (!syntax_->isS(event->data()[i])) match = 0; do { i++; } while (i < event->dataLength() && syntax_->isS(event->data()[i])); for (size_t j = 0; j < arcBase_.size() && match; i++, j++) if (i >= event->dataLength() || (*syntax_->generalSubstTable())[event->data()[i]] != arcBase_[j]) match = 0; if (i >= event->dataLength() || !syntax_->isS(event->data()[i])) match = 0; if (match) { size_t dataLength = event->dataLength(); const Char *data = event->data(); for (;;) { while (i < dataLength && syntax_->isS(data[i])) i++; if (i >= dataLength) break; size_t start = i++; while (i < dataLength && !syntax_->isS(data[i])) i++; StringC name(data + start, i - start); syntax_->generalSubstTable()->subst(name); arcProcessors_.resize(arcProcessors_.size() + 1); arcProcessors_.back().setName(name); } } } DelegateEventHandler::pi(event);}void ArcEngineImpl::endProlog(EndPrologEvent *event){ currentLocation_ = event->location(); for (size_t i = 0; i < arcProcessors_.size(); i++) arcProcessors_[i].init(*event, sd_, syntax_, parser_, this, docName_, *director_, cancelPtr_); if (!event->lpdPointer().isNull()) { haveLinkProcess_ = 1; linkProcess_.init(event->lpdPointer()); } DelegateEventHandler::endProlog(event);}void ArcEngineImpl::startDtd(StartDtdEvent *event){ stage_++; DelegateEventHandler::startDtd(event);}void ArcEngineImpl::endDtd(EndDtdEvent *event){ stage_++; DelegateEventHandler::endDtd(event);}void ArcEngineImpl::startLpd(StartLpdEvent *event){ if (event->active()) stage_ = 1; DelegateEventHandler::startLpd(event);}void ArcEngineImpl::endLpd(EndLpdEvent *event){ stage_++; DelegateEventHandler::endLpd(event);}void ArcEngineImpl::sgmlDecl(SgmlDeclEvent *event){ currentLocation_ = event->location(); sd_ = event->sdPointer(); syntax_ = event->instanceSyntaxPointer(); arcBase_ = sd_->execToInternal("ArcBase"); syntax_->generalSubstTable()->subst(arcBase_); is10744_ = sd_->execToInternal("IS10744"); Boolean atStart = 1; for (size_t i = 0; i < appinfo_.size(); i++) if (syntax_->isS(appinfo_[i])) atStart = 1; else if (atStart) { if (i + 7 > appinfo_.size()) break; StringC tem(appinfo_.data() + i, 7); syntax_->generalSubstTable()->subst(tem); if (tem == arcBase_) { if (i + 7 == appinfo_.size() || syntax_->isS(appinfo_[i + 7])) break; if (appinfo_[i + 7] == sd_->execToInternal('=')) { arcBase_.resize(0); for (size_t j = i + 7; j < appinfo_.size(); j++) { if (syntax_->isS(appinfo_[j])) break; arcBase_ += appinfo_[j]; } // Allow quotes around replacement name. if (arcBase_.size() > 2 && (arcBase_[0] == sd_->execToInternal('"') || arcBase_[0] == sd_->execToInternal('\'')) && arcBase_[arcBase_.size() - 1] == arcBase_[0]) { for (size_t j = 0; j < arcBase_.size() - 2; j++) arcBase_[j] = arcBase_[j + 1]; arcBase_.resize(arcBase_.size() - 2); } syntax_->generalSubstTable()->subst(arcBase_); break; } } atStart = 0; } DelegateEventHandler::sgmlDecl(event);}void ArcEngineImpl::startElement(StartElementEvent *event){ if (gatheringContent_) { gatheringContent_++; DelegateEventHandler::startElement(event); return; } currentLocation_ = event->location(); const Text *contentP; size_t start; if (startAgain_) { start = startAgain_ - 1; contentP = &content_; startAgain_ = 0; } else { contentP = 0; start = 0; if (haveLinkProcess_) { const ResultElementSpec *resultElementSpec; linkProcess_.startElement(event->elementType(), event->attributes(), event->location(), *this, // Messenger & linkAttributes_, resultElementSpec); } else linkAttributes_ = 0; } for (size_t i = start; i < arcProcessors_.size(); i++) { if (arcProcessors_[i].valid()) { if (!arcProcessors_[i].processStartElement(*event, linkAttributes_, contentP, alloc_)) { ASSERT(contentP == 0); startAgain_ = i + 1; gatheringContent_ = 1; delegateTo_ = &eventQueue_; DelegateEventHandler::startElement(event); return; } } } content_.clear(); DelegateEventHandler::startElement(event);}void ArcEngineImpl::data(DataEvent *event){ const Entity *entity = event->entity(); if (gatheringContent_) { if (entity) content_.addCdata(entity->asInternalEntity()->string(), event->location().origin()); else { // Do attribute value literal interpretation. Location loc(event->location()); for (size_t i = 0; i < event->dataLength(); i++, loc += 1) { Char ch = event->data()[i]; if (syntax_->isS(ch) && ch != syntax_->space()) { if (ch == syntax_->standardFunction(Syntax::fRS)) content_.ignoreChar(ch, loc); else content_.addChar(syntax_->space(), Location(new ReplacementOrigin(loc, ch), 0)); } else content_.addChar(ch, loc); } } } else { currentLocation_ = event->location(); for (size_t i = 0; i < arcProcessors_.size(); i++) { if (arcProcessors_[i].valid() && arcProcessors_[i].processData()) { if (entity) arcProcessors_[i].docHandler() .data(new (alloc_) CdataEntityEvent(entity->asInternalEntity(), event->location().origin())); else arcProcessors_[i].docHandler() .data(new (alloc_) ImmediateDataEvent(event->type(), event->data(), event->dataLength(), event->location(), 0)); } } } DelegateEventHandler::data(event);}void ArcEngineImpl::sdataEntity(SdataEntityEvent *event){ if (gatheringContent_) { content_.addSdata(event->entity()->asInternalEntity()->string(), event->location().origin());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -