⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 copyeventhandler.cxx

📁 SP是一个基于GNU C++编译器
💻 CXX
📖 第 1 页 / 共 2 页
字号:
// Copyright (c) 1995 James Clark// See the file COPYING for copying permission.#ifdef __GNUG__#pragma implementation#endif#include "config.h"#include "CopyEventHandler.h"#include "macros.h"#ifdef SP_NAMESPACEnamespace SP_NAMESPACE {#endifinlineOutputCharStream &operator<<(OutputCharStream &os, const MarkupIter &iter){  return os.write(iter.charsPointer(), iter.charsLength());}#ifdef __GNUG__inline#endifBoolean CopyEventHandler::noOutput(){  if (inInstance_) {    if (normalizeFlags_ & normalizeExpand) {      if (entityLevel_ >= outputEntityLevel_)	return 0;    }    else {      if (entityLevel_ == outputEntityLevel_)	return 0;    }  }  else if (normalizeFlags_ & normalizeIncludeProlog) {    if (normalizeFlags_ & normalizeExpandProlog) {      if (entityLevel_ >= outputEntityLevel_)	return 0;    }    else {      if (entityLevel_ == outputEntityLevel_)	return 0;    }  }  return 1;}inlineBoolean CopyEventHandler::doNothing(Event *event){  if (noOutput()) {    delete event;    return 1;  }  else    return 0;}inlinevoid CopyEventHandler::withNamedCharRef(const StringC &str,					const Location &loc){  withNamedCharRef(str.data(), str.size(), loc);}staticvoid escape(OutputCharStream &s, Char c){  s << "&#" << (unsigned long)c << ";";}CopyEventHandler::CopyEventHandler(OutputCharStream *os,				   unsigned normalizeFlags,				   const StringC &outputEntity): os_(os), topOs_(os), inInstance_(0), entityLevel_(0),  normalizeFlags_(normalizeFlags), outputEntity_(outputEntity),  omittagHoist_(0), inSpecialMarkedSection_(0),  currentAttributes_(0), emptyElementNormal_(0){  outputEntityLevel_ = outputEntity_.size() == 0 ? 0 : unsigned(-1);  os_->setEscaper(escape);}CopyEventHandler::~CopyEventHandler(){  delete os_;}void CopyEventHandler::markup(const Location &loc,			      const Markup &markup){  if (!noOutput())    outputMarkup(loc, markup);}void CopyEventHandler::sgmlDecl(SgmlDeclEvent *event){  if (event->implySystemId().size() == 0      && !event->location().origin().isNull()      && (normalizeFlags_ & normalizeIncludeProlog)) {    syntax_ = event->refSyntaxPointer();    sd_ = event->refSdPointer();    outputMarkup(event->location(), event->markup());  }  syntax_ = event->prologSyntaxPointer();  instanceSyntax_ = event->instanceSyntaxPointer();  if (instanceSyntax_->namecaseGeneral())    instanceSyntax_->generalSubstTable()->inverseTable(lowerSubst_);  else if (instanceSyntax_->namecaseEntity())    instanceSyntax_->entitySubstTable()->inverseTable(lowerSubst_);  sd_ = event->sdPointer();  emptyElementNormal_ = sd_->emptyElementNormal();  delete event;}void CopyEventHandler::endProlog(EndPrologEvent *event){  inInstance_ = 1;  syntax_ = instanceSyntax_;  delete event;}void CopyEventHandler::data(DataEvent *event){  omittagHoist_ = 0;  if (doNothing(event))    return;  if (event->entity())    entityRef(event->location().origin()->asEntityOrigin());  else {    size_t n = event->dataLength();    unsigned long dummy;    if (n > 1 || !event->isRe(dummy))      writeData(event->data(), n, event->location());  }  delete event;}void CopyEventHandler::nonSgmlChar(NonSgmlCharEvent *event){  omittagHoist_ = 0;  if (doNothing(event))    return;  Char c = event->character();  writeData(&c, 1, event->location());  delete event;}void CopyEventHandler::writeData(const Char *p, size_t n,				 const Location &loc){  const Markup *markupPtr;  if (n == 1 && loc.origin()->isNumericCharRef(markupPtr)) {    if (markupPtr)      outputMarkup(loc.origin()->parent(), *markupPtr);  }  else    withNamedCharRef(p, n, loc);}void CopyEventHandler::withNamedCharRef(const Char *p, size_t n,					const Location &loc){  if (n > 0) {    const Origin *origin = loc.origin().pointer();    if (origin) {      NamedCharRef ref;      if (origin->isNamedCharRef(loc.index(), ref)) {	Markup markup;	markup.addDelim(Syntax::dCRO);	markup.addName(ref.origName().data(), ref.origName().size());	switch (ref.refEndType()) {	case NamedCharRef::endOmitted:	  break;	case NamedCharRef::endRE:	  markup.addRefEndRe();	  break;	case NamedCharRef::endRefc:	  markup.addDelim(Syntax::dREFC);	  break;	}	outputMarkup(Location(loc.origin(), ref.refStartIndex()), markup);	p++;	n--;      }    }  }  os().write(p, n);}void CopyEventHandler::reOrigin(ReOriginEvent *event){  omittagHoist_ = 0;  if (doNothing(event))    return;  Char c = event->re();  withNamedCharRef(&c, 1, event->location());  delete event;}void CopyEventHandler::sSep(SSepEvent *event){  if (doNothing(event))    return;  withNamedCharRef(event->data(), event->dataLength(), event->location());  delete event;}void CopyEventHandler::ignoredRs(IgnoredRsEvent *event){  if (doNothing(event))    return;  Char c = event->rs();  withNamedCharRef(&c, 1, event->location());  delete event;}void CopyEventHandler::startElement(StartElementEvent *event){  mustOmitEnd_ = event->mustOmitEnd();  const Markup *markup = event->markupPtr();  if (!markup) {    if (normalizeFlags_ & normalizeExpand) {      if (outputEntityLevel_ > entityLevel_ - omittagHoist_) {	delete event;	return;      }      if (omittagHoist_ >= entityStack_.size())	os_ = topOs_;    }    else if (entityLevel_ - omittagHoist_ != outputEntityLevel_) {      delete event;      return;    }  }  else {    omittagHoist_ = 0;    if (doNothing(event))      return;  }  if (normalizeFlags_ & normalizeExpandAll)    handleChange();  if (markup) {    Boolean hadName = 0;    Boolean closed = 1;    MarkupIter iter(*markup);    while (iter.valid()) {      switch (iter.type()) {      case Markup::delimiter:	switch (iter.delimGeneral()) {	case Syntax::dTAGC:	  closed = 1;	  if (!hadName) {	    StringC nameBuf;	    StringC tag(elementTypeOrigName(event->elementType(), nameBuf));	    if (normalizeFlags_ & normalizeEmptytag) {	      handleChange();	      os() << tag;	      tag.resize(0);	    }	    unspecifiedAttributeValues(event->attributes(), tag);	  }	  os() << syntax_->delimGeneral(iter.delimGeneral());	  break;	case Syntax::dNESTC:	  closed = 1;	  if (normalizeFlags_ & normalizeNet) {	    handleChange();	    os() << syntax_->delimGeneral(Syntax::dTAGC);	    break;	  }	  // fall through	default:	  os() << syntax_->delimGeneral(iter.delimGeneral());	  break;	}	iter.advance();	break;      case Markup::name:	{	  ASSERT(!hadName);	  const ElementType *elementType = event->elementType();	  if (elementType->index() >= elementTypeOrigNames_.size())	    elementTypeOrigNames_.resize(elementType->index() + 1);	  StringC &elementTypeOrigName	    = elementTypeOrigNames_[elementType->index()];	  if (elementTypeOrigName.size() == 0) {	    elementTypeOrigName.assign(iter.charsPointer(),				       iter.charsLength());	    // add rank if missing	    elementTypeOrigName.append(event->name().data() +				       elementTypeOrigName.size(),				       event->name().size()				       - elementTypeOrigName.size());	  }	  os() << iter;	  if (normalizeFlags_ & normalizeRank) {	    for (size_t i = iter.charsLength();		 i < event->name().size();		 i++) {	      handleChange();	      os().put(event->name()[i]);	    }	  }	  attributeSpecList(iter, event->attributes());	  hadName = 1;	}	break;      case Markup::s:	os() << iter;	iter.advance();	break;      default:	CANNOT_HAPPEN();      }    }    if (!closed && (normalizeFlags_ && normalizeUnclosed)) {      handleChange();      os() << syntax_->delimGeneral(Syntax::dTAGC);    }  }  else if (normalizeFlags_ & normalizeOmittag) {    if (inSpecialMarkedSection_) {      reportTagInSpecialMarkedSection(event->location());      return;    }    handleChange();    StringC nameBuf;    os() << syntax_->delimGeneral(Syntax::dSTAGO)      << elementTypeOrigName(event->elementType(), nameBuf);    unspecifiedAttributeValues(event->attributes(), StringC());    os() << syntax_->delimGeneral(Syntax::dTAGC);  }  delete event;  if (entityStack_.size() > 0 && os_ == topOs_)    os_ = &entityStack_.back().str;}void CopyEventHandler::attributeSpecList(MarkupIter &iter,					 const AttributeList &atts){  size_t nAtt = atts.size();  unsigned i;  unsigned *attIndex;  if (atts.nSpec()) {    attIndex = new unsigned[atts.nSpec()];    for (i = 0; i < atts.nSpec(); i++)      attIndex[i] = unsigned(-1);    for (i = 0; i < nAtt; i++)      if (atts.specified(i))	attIndex[atts.specIndex(i)] = i;  }  else    attIndex = 0;  Boolean hadAttname = 0;  i = 0;  StringC nameBuf;  for (iter.advance(); iter.valid(); iter.advance())    switch (iter.type()) {    case Markup::name:      os() << iter;      hadAttname = 1;      break;    case Markup::s:      os() << iter;      break;    case Markup::attributeValue:      if (!hadAttname	  && attIndex	  && attIndex[i] != unsigned(-1)	  && (normalizeFlags_ & (normalizeAttname | normalizeAttvalue))) {	handleChange();	os() << generalName(atts.name(attIndex[i]), nameBuf)	  << syntax_->delimGeneral(Syntax::dVI);      }      if (normalizeFlags_ & normalizeAttvalue) {	handleChange();	os() << syntax_->delimGeneral(Syntax::dLIT)	  << iter	    << syntax_->delimGeneral(Syntax::dLIT);      }      else	os() << iter;      hadAttname = 0;      i++;      break;    case Markup::literal:      literal(iter.text());      i++;      hadAttname = 0;      break;    case Markup::delimiter:      if (iter.delimGeneral() == Syntax::dVI)	os() << syntax_->delimGeneral(iter.delimGeneral());      else {	unspecifiedAttributeValues(atts, StringC());	delete [] attIndex;	return;      }      break;    default:      CANNOT_HAPPEN();    }}void CopyEventHandler::unspecifiedAttributeValues(const AttributeList &atts,						  const StringC &beforeFirst){  if (normalizeFlags_ & (normalizeCurrent|normalizeAttspec)) {    Boolean first = 1;    size_t nAtt = atts.size();    StringC nameBuf;    for (unsigned i = 0; i < nAtt; i++) {      const Text *text;      if (!atts.specified(i)	  && ((normalizeFlags_ & normalizeAttspec)	      || atts.current(i))	  && atts.value(i)	  && (text = atts.value(i)->text()) != 0) {	if (first) {	  handleChange();	  os() << beforeFirst;	  first = 0;	}	os().put(syntax_->standardFunction(Syntax::fSPACE));	os() << generalName(atts.name(i), nameBuf)	  << syntax_->delimGeneral(Syntax::dVI);	Boolean lita;	if (text->delimType(lita))	  literal(*text);	else {	  if (normalizeFlags_ & normalizeAttvalue) {	    os() << syntax_->delimGeneral(Syntax::dLIT)	      << text->string()		<<  syntax_->delimGeneral(Syntax::dLIT);	  }	  else	    os() << text->string();	}      }    }  }}void CopyEventHandler::literal(const Text &text){  TextIter iter(text);  TextItem::Type type;  const Char *p;  size_t n;  const Location *loc;  StringC delim;  Boolean lita;  if (!text.delimType(lita))    CANNOT_HAPPEN();  delim = syntax_->delimGeneral(lita ? Syntax::dLITA : Syntax::dLIT);  os() << delim;  int level = 0;  while (iter.next(type, p, n, loc)) {    switch (type) {    case TextItem::ignore:    case TextItem::data:    case TextItem::nonSgml:      if (!level) {	const Char *orig;	if (loc->origin()->origChars(orig))	  writeData(orig, n, loc->origin()->parent());	else	  writeData(p, n, *loc);      }      break;    case TextItem::cdata:    case TextItem::sdata:      if (!level)	entityRef(loc->origin()->asEntityOrigin());      break;    case TextItem::entityStart:      if (!level++)	entityRef(loc->origin()->asEntityOrigin());      break;    case TextItem::entityEnd:      level--;      break;    case TextItem::startDelim:    case TextItem::endDelim:    case TextItem::endDelimA:      break;    }  }  Location delimLoc;  if (!text.endDelimLocation(delimLoc))    CANNOT_HAPPEN();  withNamedCharRef(delim, delimLoc);}void CopyEventHandler::endElement(EndElementEvent *event){  if (!emptyElementNormal_ && mustOmitEnd_) {    delete event;    mustOmitEnd_ = 0;    return;  }  const Markup *markup = event->markupPtr();  if (!markup) {    if (normalizeFlags_ & normalizeExpand) {      if (outputEntityLevel_ > entityLevel_ - omittagHoist_) {	delete event;	return;      }      if (omittagHoist_ >= entityStack_.size())	os_ = topOs_;    }    else if (entityLevel_ - omittagHoist_ != outputEntityLevel_) {      delete event;      return;    }  }  else {    omittagHoist_ = 0;    if (doNothing(event))      return;  }  if (normalizeFlags_ & normalizeExpandAll)    handleChange();  if (markup) {    Boolean closed = 0;    Boolean hadAttname = 0;    for (MarkupIter iter(*markup); iter.valid(); iter.advance())      switch (iter.type()) {      case Markup::s:	os() << iter;	break;      case Markup::name:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -