📄 soentitycatalog.cxx
字号:
// Copyright (c) 1994, 1995, 1996 James Clark// See the file COPYING for copying permission.#ifdef __GNUG__#pragma implementation#endif#include "splib.h"#include "CharsetInfo.h"#include "MessageArg.h"#include "CatalogMessages.h"#include "SOEntityCatalog.h"#include "EntityDecl.h"#include "EntityCatalog.h"#include "Message.h"#include "StringC.h"#include "types.h"#include "HashTable.h"#include "InputSource.h"#include "Boolean.h"#include "SubstTable.h"#include "CatalogEntry.h"#include "Vector.h"#include "StorageManager.h"#include "macros.h"#ifdef SP_NAMESPACEnamespace SP_NAMESPACE {#endifclass CatalogParser;class SOEntityCatalog;class SOCatalogManagerImpl : public SOCatalogManager {public: SOCatalogManagerImpl(const Vector<StringC> &sysids, size_t nSysidsMustExist, const CharsetInfo *sysidCharset, const CharsetInfo *catalogCharset, Boolean useDocCatalog); ConstPtr<EntityCatalog> makeCatalog(StringC &systemId, const CharsetInfo &charset, ExtendEntityManager *, Messenger &) const; Boolean mapCatalog(ParsedSystemId &systemId, ExtendEntityManager *em, Messenger &mgr) const;private: void addCatalogsForDocument(CatalogParser &parser, StringC &sysid, SOEntityCatalog *, const CharsetInfo &charset, Messenger &mgr) const; size_t nSystemCatalogsMustExist_; Vector<StringC> systemCatalogs_; const CharsetInfo *sysidCharset_; const CharsetInfo *catalogCharset_; Boolean useDocCatalog_;};class SOEntityCatalog : public EntityCatalog {public: SOEntityCatalog(Ptr<ExtendEntityManager> em); typedef EntityDecl::DeclType DeclType; Boolean document(const CharsetInfo &, Messenger &, StringC &) const; Boolean sgmlDecl(const CharsetInfo &, Messenger &, StringC &) const; Boolean lookup(const EntityDecl &entity, const Syntax &, const CharsetInfo &, Messenger &, StringC &) const; Boolean lookupPublic(const StringC &, const CharsetInfo &, Messenger &, StringC &) const; Boolean lookupChar(const StringC &, const CharsetInfo &, Messenger &, UnivChar &) const; void addPublicId(StringC &publicId, StringC &systemId, const Location &, Boolean override); void addDelegate(StringC &prefix, StringC &systemId, const Location &, Boolean override); void addSystemId(StringC &systemId, StringC &replSystemId, const Location &); void addName(StringC &name, DeclType, StringC &systemId, const Location &, Boolean override); void setSgmlDecl(StringC &str, const Location &loc); void setDocument(StringC &str, const Location &loc); void setBase(const Location &loc); void endCatalog(); const Ptr<ExtendEntityManager> &entityManager() { return em_; }private: SOEntityCatalog(const SOEntityCatalog &); // undefined void operator=(const SOEntityCatalog &); // undefined Boolean expandCatalogSystemId(const StringC &str, const Location &loc, size_t baseNumber, Boolean isNdata, const CharsetInfo &charset, const StringC *lookupPublicId, Messenger &mgr, StringC &result) const; const CatalogEntry * findBestPublicEntry(const StringC &publicId, Boolean overrideOnly, const CharsetInfo &charset, Boolean &delegated) const; class Table { public: Table(); const CatalogEntry *lookup(const StringC &, Boolean overrideOnly) const; const CatalogEntry *lookup(const StringC &key, const SubstTable<Char> &substTable, Boolean overrideOnly) const; void insert(const StringC &, const CatalogEntry &, Boolean override); size_t count() const; private: Table(const Table &); // undefined void operator=(const Table &); // undefined // These are entries that are applicable when an explicit system id // was specified in the external identifier. HashTable<StringC,CatalogEntry> overrideEntries_; // This specifies the entries that should substitute for the // overrideEntries_ when an explicit system identifier was not specified. HashTable<StringC,CatalogEntry> normalEntries_; }; Table publicIds_; Table delegates_; HashTable<StringC,CatalogEntry> systemIds_; Table names_[5]; size_t catalogNumber_; Boolean haveSgmlDecl_; StringC sgmlDecl_; Location sgmlDeclLoc_; size_t sgmlDeclBaseNumber_; StringC document_; Boolean haveDocument_; Location documentLoc_; size_t documentBaseNumber_; Boolean haveCurrentBase_; Vector<Location> base_; Ptr<ExtendEntityManager> em_;};class CatalogParser : private Messenger {public: CatalogParser(const CharsetInfo &); void parseCatalog(const StringC &sysid, Boolean mustExist, const CharsetInfo &sysidCharset, const CharsetInfo &catalogCharset, InputSourceOrigin *origin, SOEntityCatalog *catalog, Messenger &mgr);public: // Since it's a return type, it has to be public to keep some // (broken) compilers happy. enum Param { eofParam, literalParam, nameParam, percentParam };private: enum { data, eof, nul, lit, lita, minus, s, min // other minimum data characters }; enum { minimumLiteral = 01 }; Messenger &messenger() { return *this; } void dispatchMessage(Message &); void dispatchMessage(const Message &); void initMessage(Message &); void parsePublic(); void parseDelegate(); void parseDtddecl(); void parseSystem(); void parseNameMap(EntityDecl::DeclType declType); void parseOverride(); Param parseParam(unsigned flags = 0); Boolean parseArg(); void parseLiteral(Char delim, unsigned flags); void parseName(); void skipComment(); void upcase(StringC &); Boolean inLoop(const Location &loc); Boolean isMinimumData(Xchar c) { int cat = categoryTable_[c]; return (cat == min || (cat == s && c != tab_) || cat == minus || cat == lita); } Xchar get() { return in_->get(messenger()); } void unget() { in_->ungetToken(); } Messenger *mgr_; InputSource *in_; SOEntityCatalog *catalog_; StringC param_; Location paramLoc_; Char minus_; Char tab_; Char rs_; Char re_; Char space_; StringC publicKey_; StringC systemKey_; StringC entityKey_; StringC doctypeKey_; StringC linktypeKey_; StringC notationKey_; StringC overrideKey_; StringC sgmlDeclKey_; StringC documentKey_; StringC catalogKey_; StringC yesKey_; StringC noKey_; StringC baseKey_; StringC delegateKey_; StringC dtddeclKey_; StringC sgmlKey_; XcharMap<unsigned char> categoryTable_; SubstTable<Char> substTable_; Boolean override_;};ExtendEntityManager::CatalogManager *SOCatalogManager::make(const Vector<StringC> &sysids, size_t nSysidsMustExist, const CharsetInfo *sysidCharset, const CharsetInfo *catalogCharset, Boolean useDocCatalog){ return new SOCatalogManagerImpl(sysids, nSysidsMustExist, sysidCharset, catalogCharset, useDocCatalog);} SOCatalogManagerImpl::SOCatalogManagerImpl(const Vector<StringC> &systemCatalogs, size_t nSystemCatalogsMustExist, const CharsetInfo *sysidCharset, const CharsetInfo *catalogCharset, Boolean useDocCatalog): systemCatalogs_(systemCatalogs), nSystemCatalogsMustExist_(nSystemCatalogsMustExist), sysidCharset_(sysidCharset), catalogCharset_(catalogCharset), useDocCatalog_(useDocCatalog){}Boolean SOCatalogManagerImpl::mapCatalog(ParsedSystemId &systemId, ExtendEntityManager *em, Messenger &mgr) const{ Vector<ParsedSystemId::Map> maps; systemId.maps.swap(maps); while (maps.size() > 0) { StringC catalogSystemId; systemId.unparse(*sysidCharset_, 0, catalogSystemId); SOEntityCatalog *catalog = new SOEntityCatalog(em); ConstPtr<EntityCatalog> deleter(catalog); CatalogParser parser(*catalogCharset_); parser.parseCatalog(catalogSystemId, 1, *sysidCharset_, *catalogCharset_, InputSourceOrigin::make(), catalog, mgr); // FIXME do catalog caching here StringC s; if (maps.back().type == ParsedSystemId::Map::catalogDocument) { if (!catalog->document(*sysidCharset_, mgr, s)) { mgr.message(CatalogMessages::noDocumentEntry, StringMessageArg(catalogSystemId)); return 0; } } else { ASSERT(maps.back().type == ParsedSystemId::Map::catalogPublic); if (!catalog->lookupPublic(maps.back().publicId, *sysidCharset_, mgr, s)) { mgr.message(CatalogMessages::noPublicEntry, StringMessageArg(maps.back().publicId), StringMessageArg(catalogSystemId)); return 0; } } ParsedSystemId tem; if (!em->parseSystemId(s, *sysidCharset_, 0, 0, mgr, tem)) return 0; systemId = tem; maps.resize(maps.size() - 1); for (size_t i = 0; i < systemId.maps.size(); i++) maps.push_back(systemId.maps[i]); systemId.maps.clear(); } return 1;}ConstPtr<EntityCatalog>SOCatalogManagerImpl::makeCatalog(StringC &systemId, const CharsetInfo &charset, ExtendEntityManager *em, Messenger &mgr) const{ SOEntityCatalog *entityCatalog = new SOEntityCatalog(em); CatalogParser parser(*catalogCharset_); size_t i; for (i = 0; i < nSystemCatalogsMustExist_; i++) parser.parseCatalog(systemCatalogs_[i], 1, *sysidCharset_, *catalogCharset_, InputSourceOrigin::make(), entityCatalog, mgr); if (useDocCatalog_) addCatalogsForDocument(parser, systemId, entityCatalog, charset, mgr); for (i = nSystemCatalogsMustExist_; i < systemCatalogs_.size(); i++) parser.parseCatalog(systemCatalogs_[i], 0, *sysidCharset_, *catalogCharset_, InputSourceOrigin::make(), entityCatalog, mgr); return entityCatalog;}void SOCatalogManagerImpl::addCatalogsForDocument(CatalogParser &parser, StringC &sysid, SOEntityCatalog *impl, const CharsetInfo &charset, Messenger &mgr) const{ ParsedSystemId v; if (!impl->entityManager()->parseSystemId(sysid, charset, 0, 0, mgr, v)) return; if (v.maps.size() > 0) { if (v.maps[0].type == ParsedSystemId::Map::catalogDocument) { v.maps.erase(v.maps.begin(), v.maps.begin() + 1); StringC tem; v.unparse(charset, 0, tem); parser.parseCatalog(tem, 1, charset, *catalogCharset_, InputSourceOrigin::make(), impl, mgr); if (!impl->document(charset, mgr, sysid)) { mgr.message(CatalogMessages::noDocumentEntry, StringMessageArg(tem)); sysid.resize(0); } } return; } Vector<StringC> catalogs; size_t i; for (i = 0; i < v.size(); i++) if (v[i].storageManager->inheritable()) { ParsedSystemId catalogId; catalogId.resize(1); StorageObjectSpec &spec = catalogId.back(); spec.storageManager = v[i].storageManager; spec.codingSystemType = v[i].codingSystemType; spec.codingSystemName = v[i].codingSystemName; spec.specId = spec.storageManager->idCharset()->execToDesc("catalog"); spec.storageManager->resolveRelative(v[i].specId, spec.specId, 0); spec.baseId = v[i].baseId; spec.records = v[i].records; StringC tem; catalogId.unparse(charset, 0, tem); for (size_t j = 0; j < catalogs.size(); j++) if (tem == catalogs[j]) { tem.resize(0); break; } if (tem.size() > 0) { catalogs.resize(catalogs.size() + 1); tem.swap(catalogs.back()); } } for (i = 0; i < catalogs.size(); i++) parser.parseCatalog(catalogs[i], 0, charset, *catalogCharset_, InputSourceOrigin::make(), impl, mgr);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -