📄 rasteventhandler.cxx
字号:
externalIdInfo(entity->externalId()); os() << "#NOTATION=" << entity->notation()->name() << nl; externalIdInfo(entity->notation()->externalId()); attributeInfo(entity->attributes(), (attributeType == resultAttribute ? resultAttribute : dtdAttribute));}void RastEventHandler::subdocEntity(SubdocEntityEvent *event){ const SubdocEntity *entity = event->entity(); if (!entity) return; flushLine(dataLine); os() << "[&" << entity->name() << nl; Ptr<InputSourceOrigin> origin(event->entityOrigin()->copy()); subdocEntityInfo(entity, origin, 1); os() << ']' << nl; delete event;}void RastEventHandler::subdocEntityInfo(const SubdocEntity *entity, const Ptr<InputSourceOrigin> &entityOrigin, Boolean referenced){ os() << "#SUBDOC" << nl; externalIdInfo(entity->externalId()); if (parseNextSubdoc()) { // FIXME subdocuments in entity attributes shouldn't count against // SUBDOC quantity limit. os() << "#PARSED-SUBDOCUMENT" << nl; SgmlParser::Params params; params.entityType = SgmlParser::Params::subdoc; params.subdocInheritActiveLinkTypes = 0; params.subdocReferenced = referenced; params.parent = parser_; params.sysid = entity->externalId().effectiveSystemId(); params.origin = entityOrigin; SgmlParser parser(params); RastSubdocState oldSubdocState; RastSubdocState::swap(oldSubdocState); RastSubdocState::init(&parser, this); parser.parseAll(*this); oldSubdocState.swap(*this); }}void RastEventHandler::queueParseSubdoc(Boolean parseSubdoc){ parseSubdocQueue_.push_back(PackedBoolean(parseSubdoc));}Boolean RastEventHandler::parseNextSubdoc(){ if (parseSubdocQueue_.size() == 0) return 0; Boolean result = parseSubdocQueue_[0]; if (parseSubdocQueue_.size() > 1) { for (size_t i = 1; i < parseSubdocQueue_.size(); i++) parseSubdocQueue_[i - 1] = parseSubdocQueue_[i]; } parseSubdocQueue_.resize(parseSubdocQueue_.size() - 1); return result;}void RastEventHandler::externalIdInfo(const ExternalId &id){ const StringC *systemId = id.systemIdString(); const StringC *publicId = id.publicIdString(); if (publicId) { os() << "#PUBLIC" << nl; if (publicId->size() == 0) os() << "#EMPTY" << nl; else { lines(markupLine, publicId->data(), publicId->size()); flushLine(markupLine); } } if (systemId || !publicId) { os() << "#SYSTEM" << nl; if (!systemId) os() << "#NONE" << nl; else if (systemId->size() == 0) os() << "#EMPTY" << nl; else { lines(markupLine, systemId->data(), systemId->size()); flushLine(markupLine); } }}void RastEventHandler::nonSgmlChar(NonSgmlCharEvent *event){ flushLine(dataLine); os() <<'#' << (unsigned long)event->character() << nl; delete event;}void RastEventHandler::lines(LineType type, const Char *p, size_t length){ // This needs to be fast. while (length != 0) { if (printable(*p)) { size_t lim; switch (lineLength_) { case maxLineLength: os() << char(type) << nl; lineLength_ = 0; // fall through case 0: os() << char(type); lim = maxLineLength; break; default: lim = maxLineLength - lineLength_; break; } if (lim > length) lim = length; size_t n = lim; for (;;) { os().put(*p); p++; if (--n == 0) break; if (!printable(*p)) { lim -= n; break; } } length -= lim; lineLength_ += lim; } else { // *p is an unprintable character print it flushLine(type); switch (*p) { case RS: os() << "#RS" << nl; break; case RE: os() << "#RE" << nl; break; case TAB: os() << "#TAB" << nl; break; default: os() << '#' << (unsigned long)*p << nl; break; } p++; length--; } }}int RastEventHandler::lexCmp(const StringC &s1, const StringC &s2){ const Char *p1 = s1.data(); size_t n1 = s1.size(); const Char *p2 = s2.data(); size_t n2 = s2.size(); for (;;) { if (n1 == 0) return n2 == 0 ? 0 : -1; if (n2 == 0) return 1; if (*p1 != *p2) { // printable characters precede non-printable characters; // printable characters are in ASCII order // non-printable characters are in document character set order int a1 = printable(*p1); int a2 = printable(*p2); if (a1 == 0) { if (a2 == 0) return *p1 < *p2 ? -1 : 1; else return 1; } else if (a2 == 0) return -1; else return a1 - a2; } p1++; p2++; n1--; n2--; }}void RastEventHandler::attributeInfo(const AttributeList &attributes, AttributeType attributeType){ size_t length = attributes.size(); if (length == 0) return; size_t defIndex = attributes.defIndex(); if (defIndex >= attributeSortOrder_[attributeType].size()) attributeSortOrder_[attributeType].resize(defIndex + 1); Vector<size_t> &sortOrder = attributeSortOrder_[attributeType][defIndex]; if (sortOrder.size() != length || attributeType == simpleAttribute) { sortOrder.resize(length); size_t i; for (i = 0; i < length; i++) sortOrder[i] = i; // insertion sort for (i = 1; i < length; i++) { size_t tem = sortOrder[i]; size_t j; for (j = i; j > 0; j--) { if (lexCmp(attributes.name(sortOrder[j - 1]), attributes.name(tem)) <= 0) break; sortOrder[j] = sortOrder[j - 1]; } sortOrder[j] = tem; } } for (size_t j = 0; j < length; j++) { // Don't use sortOrder because attributeSortOrder_ may be grown // because of data attributes. size_t i = attributeSortOrder_[attributeType][defIndex][j]; os() << attributes.name(i) << '=' << nl; const Text *text; const StringC *string; const AttributeValue *value = attributes.value(i); if (value) { switch (value->info(text, string)) { case AttributeValue::implied: os() << "#IMPLIED" << nl; break; case AttributeValue::tokenized: lines(markupLine, string->data(), string->size()); flushLine(markupLine); break; case AttributeValue::cdata: { TextIter iter(*text); TextItem::Type type; const Char *p; size_t length; const Location *loc; while (iter.next(type, p, length, loc)) switch (type) { case TextItem::data: case TextItem::cdata: lines(markupLine, p, length); break; case TextItem::sdata: flushLine(markupLine); os() << "#SDATA-TEXT" << nl; lines(markupLine, p, length); flushLine(markupLine); os() << "#END-SDATA" << nl; break; case TextItem::nonSgml: flushLine(markupLine); os() << '#' << (unsigned long)*p << nl; break; default: break; } flushLine(markupLine); } break; } } const AttributeSemantics *semantics = attributes.semantics(i); if (semantics) { ConstPtr<Notation> notation = semantics->notation(); if (!notation.isNull()) externalIdInfo(notation->externalId()); size_t nEntities = semantics->nEntities(); for (size_t i = 0; i < nEntities; i++) { ConstPtr<Entity> entity = semantics->entity(i); if (!entity.isNull()) { const ExternalDataEntity *externalDataEntity = entity->asExternalDataEntity(); if (externalDataEntity) externalEntityInfo(externalDataEntity, (attributeType == resultAttribute ? resultAttribute : dtdAttribute)); else { const SubdocEntity *subdocEntity = entity->asSubdocEntity(); if (subdocEntity) { Ptr<InputSourceOrigin> entityOrigin = EntityOrigin::make(entity, ((TokenizedAttributeValue *)value) ->tokenLocation(i)); subdocEntityInfo(subdocEntity, entityOrigin, 0); } else { const InternalEntity *internalEntity = entity->asInternalEntity(); if (internalEntity) internalEntityInfo(internalEntity); } } } os() << "#END-ENTITY" << nl; } } }}void RastEventHandler::internalEntityInfo(const InternalEntity *entity){ if (!entity) return; os() << '#' << char(entity->dataType() == Entity::cdata ? 'C' : 'S') << "DATA-INTERNAL" << nl; const StringC &str = entity->string(); lines(markupLine, str.data(), str.size()); flushLine(markupLine);}void RastEventHandler::endProlog(EndPrologEvent *event){ if (!event->lpdPointer().isNull()) { linkProcess_.init(event->lpdPointer()); haveLinkProcess_ = 1; } if (event->simpleLinkNames().size() > 0) endPrologEvent_ = event; else delete event;}void RastEventHandler::uselink(UselinkEvent *event){ linkProcess_.uselink(event->linkSet(), event->restore(), event->lpd().pointer()); if (haveLinkProcess_ && linkProcess_.nImpliedLinkRules() > 0) { flushLine(dataLine); os() << "#LINK-SET-INFO" << nl; impliedSourceLinkRules(); os() << "#END-LINK-SET-INFO" << nl; } delete event;}void RastEventHandler::initMessage(Message &msg){ mgr_->initMessage(msg);}void RastEventHandler::dispatchMessage(const Message &msg){ if (msg.isError()) piErrorCount_++; if (!cancelled()) { noteMessage(msg); mgr_->dispatchMessage(msg); }}RastLinkProcess::RastLinkProcess(): rast_(0){}void RastLinkProcess::setHandler(RastEventHandler *rast){ rast_ = rast;}// Always return 1. 0 means not ready.Boolean RastLinkProcess::selectLinkRule(const Vector<const AttributeList *> &linkAttributes, const Location &location, size_t &selected){ if (!rast_->linkRuleQueue_.empty()) { LinkRulePi *p = rast_->linkRuleQueue_.get(); if (!selectLinkRulePi(p->pi, p->loc, linkAttributes, selected)) selected = 0; } else { if (linkAttributes.size() > 0) { rast_->setNextLocation(location); rast_->Messenger::message(RastEventHandlerMessages::multipleLinkRules); } selected = 0; } return 1;}// Return zero for failure (RAST-PI-ERROR).Boolean RastLinkProcess::selectLinkRulePi(const StringC &value, const Location &loc, const Vector<const AttributeList *> &linkAttributes, size_t &selected){ Boolean haveSelection = 0; size_t i; for (i = 0; i < linkAttributes.size(); i++) { const AttributeList &a = *linkAttributes[i]; Boolean matchValue = 0; for (size_t j = 0; j < a.size(); j++) { const Text *textp; const StringC *strp; switch (a.value(j)->info(textp, strp)) { case AttributeValue::cdata: // What if it contains SDATA entities? if (textp->string() == value) matchValue = 1; break; case AttributeValue::tokenized: if (*strp == value) matchValue = 1; break; default: break; } if (matchValue) break; } if (matchValue) { if (haveSelection) { rast_->setNextLocation(loc); rast_->Messenger::message(RastEventHandlerMessages::multipleLinkRuleMatch); return 0; } haveSelection = 1; selected = i; } } if (!haveSelection) { rast_->setNextLocation(loc); rast_->Messenger::message(RastEventHandlerMessages::noLinkRuleMatch); return 0; } return 1;}void RastLinkProcess::swap(RastLinkProcess &to){ LinkProcess::swap(to); RastEventHandler *tem = to.rast_; to.rast_ = rast_; rast_ = tem;}#ifdef SP_NAMESPACE}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -