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

📄 xmloutputeventhandler.cxx

📁 SP是一个基于GNU C++编译器
💻 CXX
📖 第 1 页 / 共 2 页
字号:
// Copyright (c) 1997 James Clark// See the file COPYING for copying permission.#ifdef __GNUG__#pragma implementation#endif#include "config.h"#include "XmlOutputEventHandler.h"#include "XmlOutputMessages.h"#include "Message.h"#include "MessageArg.h"#include "macros.h"#if 0#include "UTF8CodingSystem.h"#endif#include "InputSource.h"#include "StorageManager.h"#include <string.h>#ifdef SP_NAMESPACEnamespace SP_NAMESPACE {#endifinlinevoid operator+=(StringC &str, const char *s){  while (*s)    str += *s++;}inlinevoid XmlOutputEventHandler::closeCdataSection(){  useCdata_ = 0;  if (inCdata_) {    os() << "]]>";    inCdata_ = 0;    nCdataEndMatched_ = 0;  }}const char RE = '\r';XmlOutputEventHandler::Options::Options(){  memset(this, 0, sizeof(*this));}staticvoid escape(OutputCharStream &s, Char c){  s << "&#" << (unsigned long)c << ";";}XmlOutputEventHandler::XmlOutputEventHandler(const Options &options,					     OutputCharStream *os,					     const StringC &encodingName,					     const Ptr<ExtendEntityManager> &entityManager,					     const CharsetInfo &systemCharset,					     Messenger *mgr): options_(options),  os_(os),  entityManager_(entityManager),  systemCharset_(&systemCharset),  mgr_(mgr),  inDtd_(0),  inCdata_(0),  useCdata_(0),  nCdataEndMatched_(0),  namecaseGeneral_(0){  os_->setEscaper(escape);  *os_ << "<?xml version=\"1.0\"";  if (encodingName.size())    *os_ << " encoding=\"" << encodingName << '"';  *os_ << "?>" << RE;}XmlOutputEventHandler::~XmlOutputEventHandler(){  os() << RE;  delete os_;}void XmlOutputEventHandler::message(MessageEvent *event){  mgr_->dispatchMessage(event->message());  ErrorCountEventHandler::message(event);}void XmlOutputEventHandler::sgmlDecl(SgmlDeclEvent *event){  const Syntax &syntax = event->instanceSyntax();  if (syntax.namecaseGeneral()) {    namecaseGeneral_ = 1;    syntax.generalSubstTable()->inverseTable(lowerSubst_);  }  delete event;}void XmlOutputEventHandler::data(DataEvent *event){  if (useCdata_)    outputCdata(event->data(), event->dataLength());  else    outputData(event->data(), event->dataLength(), 0);  delete event;}void XmlOutputEventHandler::startElement(StartElementEvent *event){  // This shouldn't happen (although useCdata_ can be true).  if (inCdata_) {    inCdata_ = 0;    nCdataEndMatched_ = 0;    os() << "]]>";  }  os() << '<' << generalName(event->name(), nameBuf_);  size_t nAttributes = event->attributes().size();  for (size_t i = 0; i < nAttributes; i++)    outputAttribute(event->attributes(), i);  if (options_.nlInTag)    os() << RE;  if (options_.cdata      && event->elementType()->definition()->declaredContent() == ElementDefinition::cdata)    useCdata_ = 1;  if (options_.empty      && event->elementType()->definition()->declaredContent() == ElementDefinition::empty)    os() << "/>";  else    os() << '>';  delete event;}void XmlOutputEventHandler::outputAttribute(const AttributeList &attributes, size_t i){  const AttributeValue *value = attributes.value(i);  if (!value)    return;  const Text *text;  const StringC *string;  AttributeValue::Type type = value->info(text, string);  if (type == AttributeValue::implied)    return;  if (options_.nlInTag)    os() << RE;  else    os() << ' ';  os() << generalName(attributes.name(i), nameBuf_) << "=\"";  if (type == 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:	outputData(p, length, 1);	break;      case TextItem::sdata:	{	  mgr_->setNextLocation(loc->origin()->parent());	  const Entity *entity = loc->origin()->asEntityOrigin()->entity();	  mgr_->message(XmlOutputMessages::sdataEntityReference,			StringMessageArg(entity->name()));	  os() << '&' << entity->name() << ';';	}	break;      case TextItem::nonSgml:	// FIXME  	break;      default:	break;      }    }  }  else if (attributes.def()->def(i)->isEntity())    os() << *string;  else    os() << generalName(*string, nameBuf_);  os() << '"';}void XmlOutputEventHandler::endElement(EndElementEvent *event){  closeCdataSection();  if (options_.empty      && event->elementType()->definition()->declaredContent() == ElementDefinition::empty)    ;  else {    os() << "</" << generalName(event->name(), nameBuf_);#if 0    if (options_.nlInTag)      os() << RE;#endif    os() << '>';  }  delete event;}static Boolean isXmlS(Char c){  switch (c) {  case ' ':  case '\r':  case '\n':  case '\t':    return 1;  }  return 0;}static Boolean containsQuestionLt(const Char *s, size_t n){  for (; n > 1; n--, s++)    if (*s == '?' && s[1] == '>')      return 1;  return 0;}// These do not handle Unicode chars properly.// They treat all Unicode chars >= 170 as name start charactersstatic Boolean isXmlNameStartChar(Char c){  switch (c) {  case ':':  case '.':  case '_':  case '-':    return 1;  }  if (c >= 170)    return 1;  if ('a' <= c && c <= 'z')    return 1;  if ('A' <= c && c <= 'Z')    return 1;  return 0;}static Boolean isXmlNameChar(Char c){  if (isXmlNameStartChar(c))    return 1;  if ('0' <= c && c <= '9')    return 1;  return 0;}static Boolean startsWithXmlName(const Char *s, size_t n){  if (n == 0)    return 0;  if (!isXmlNameStartChar(*s))    return 0;  for (s++, n--; n > 0; n--, s++) {    if (isXmlS(*s))      return 1;    if (!isXmlNameChar(*s))      return 0;  }  return 1;}void XmlOutputEventHandler::pi(PiEvent *event){  const Char *s = event->data();  size_t n = event->dataLength();  if (n >= 3 && s[0] == 'x' && s[1] == 'm' && s[2] == 'l'           && (n == 3 || isXmlS(s[3])))    ; // Probably came from an encoding PI.  else if (!startsWithXmlName(s, n)) {    mgr_->setNextLocation(event->location());    mgr_->message(XmlOutputMessages::piNoName);  }  else if (options_.piEscape) {    os() << "<?";    outputData(s, n, 0);    os() << "?>";  }  else if (containsQuestionLt(s, n)) {    mgr_->setNextLocation(event->location());    mgr_->message(XmlOutputMessages::piQuestionLt);  }  else {    os() << "<?";    os().write(s, n);    os() << "?>";  }  delete event;}void XmlOutputEventHandler::sdataEntity(SdataEntityEvent *event){  mgr_->setNextLocation(event->location().origin()->parent());  mgr_->message(XmlOutputMessages::sdataEntityReference,                StringMessageArg(event->entity()->name()));  os() << '&' << event->entity()->name() << ';';  delete event;}void XmlOutputEventHandler::externalDataEntity(ExternalDataEntityEvent *event){  mgr_->setNextLocation(event->location().origin()->parent());  mgr_->message(XmlOutputMessages::externalDataEntityReference,                StringMessageArg(event->entity()->name()));  os() << (options_.lower ? "<entity name=\"" : "<ENTITY NAME=\"")       << event->entity()->name() << "\"/>";  delete event;}void XmlOutputEventHandler::subdocEntity(SubdocEntityEvent *event){  mgr_->setNextLocation(event->location().origin()->parent());  mgr_->message(XmlOutputMessages::subdocEntityReference,                StringMessageArg(event->entity()->name()));  os() << (options_.lower ? "<entity name=\"" : "<ENTITY NAME=\"")       << event->entity()->name() << "\"/>";  delete event;}void XmlOutputEventHandler::startDtd(StartDtdEvent *event){  inDtd_ = 1;  delete event;}void XmlOutputEventHandler::endDtd(EndDtdEvent *event){  inDtd_ = 0;  delete event;}void XmlOutputEventHandler::maybeStartDoctype(Boolean &doctypeStarted, const Dtd &dtd){  if (doctypeStarted)    return;  doctypeStarted = 1;  os() << "<!DOCTYPE " << dtd.documentElementType()->name() << " [" << RE;}void XmlOutputEventHandler::endProlog(EndPrologEvent *event){  const Dtd &dtd = event->dtd();  Boolean doctypeStarted = 0;  if (options_.notation) {    Dtd::ConstNotationIter iter(dtd.notationIter());    for (;;) {      const Notation *notation = iter.nextTemp();      if (!notation)	break;      maybeStartDoctype(doctypeStarted, dtd);      os() << "<!NOTATION " << generalName(notation->name(), nameBuf_);      outputExternalId(*notation);      os() << ">" << RE;      if (notation->attributeDefTemp()) {	mgr_->setNextLocation(notation->defLocation());	mgr_->message(XmlOutputMessages::notationAttributes,

⌨️ 快捷键说明

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