📄 soentitycatalog.cxx
字号:
SOEntityCatalog::SOEntityCatalog(Ptr<ExtendEntityManager> em): em_(em), catalogNumber_(0), haveSgmlDecl_(0), haveDocument_(0), haveCurrentBase_(0){}void SOEntityCatalog::endCatalog(){ catalogNumber_++; haveCurrentBase_ = 0;}Boolean SOEntityCatalog::expandCatalogSystemId(const StringC &str, const Location &loc, size_t baseNumber, Boolean isNdata, const CharsetInfo &charset, const StringC *lookupPublicId, Messenger &mgr, StringC &result) const{ return em_->expandSystemId(str, (baseNumber ? base_[baseNumber - 1] : loc), isNdata, charset, lookupPublicId, mgr, result);}Boolean SOEntityCatalog::lookup(const EntityDecl &entity, const Syntax &syntax, const CharsetInfo &charset, Messenger &mgr, StringC &result) const{ const CatalogEntry *entry = 0; const CatalogEntry *delegatedEntry = 0; if (entity.systemIdPointer()) entry = systemIds_.lookup(*entity.systemIdPointer()); if (entity.publicIdPointer()) { const CatalogEntry *publicEntry; Boolean delegated; publicEntry = findBestPublicEntry(*entity.publicIdPointer(), entity.systemIdPointer() != 0, charset, delegated); if (publicEntry && delegated) delegatedEntry = publicEntry; // match for system id has priority over match for public id in same // catalog if (publicEntry && (!entry || publicEntry->catalogNumber < entry->catalogNumber)) entry = publicEntry; } if (entity.name().size() > 0 && (!entry || entry->catalogNumber > 0)) { const CatalogEntry *entityEntry; int tableIndex = (entity.declType() >= EntityDecl::parameterEntity ? int(entity.declType()) - 1 : int(entity.declType())); StringC name(entity.name()); Boolean subst; switch (entity.declType()) { case EntityDecl::parameterEntity: { StringC tem(name); name = syntax.peroDelim(); name += tem; } // fall through case EntityDecl::generalEntity: subst = syntax.namecaseEntity(); break; default: subst = syntax.namecaseGeneral(); break; } if (!subst) entityEntry = names_[tableIndex].lookup(name, entity.systemIdPointer() != 0); else entityEntry = names_[tableIndex].lookup(name, syntax.upperSubstTable(), entity.systemIdPointer() != 0); // match for public id has priority over match for entity in same // catalog if (entityEntry && (!entry || entityEntry->catalogNumber < entry->catalogNumber)) entry = entityEntry; } if (entry) return expandCatalogSystemId(entry->to, entry->loc, entry->baseNumber, entity.dataType() == EntityDecl::ndata, charset, entry == delegatedEntry ? entity.publicIdPointer() : 0, mgr, result); if (entity.systemIdPointer()) return em_->expandSystemId(*entity.systemIdPointer(), entity.defLocation(), entity.dataType() == EntityDecl::ndata, charset, 0, mgr, result); return 0;}Boolean SOEntityCatalog::lookupPublic(const StringC &publicId, const CharsetInfo &charset, Messenger &mgr, StringC &result) const{ Boolean delegated; const CatalogEntry *entry = findBestPublicEntry(publicId, 0, charset, delegated); return (entry && expandCatalogSystemId(entry->to, entry->loc, entry->baseNumber, 0, charset, delegated ? &publicId : 0, mgr, result)); }Boolean SOEntityCatalog::lookupChar(const StringC &name, const CharsetInfo &charset, Messenger &mgr, UnivChar &result) const{ Boolean delegated; const CatalogEntry *entry = findBestPublicEntry(name, 0, charset, delegated); if (!entry) return 0; if (delegated) return 0; // FIXME const StringC &number = entry->to; if (number.size() == 0) return 0; UnivChar n = 0; for (size_t i = 0; i < number.size(); i++) { int d = charset.digitWeight(number[i]); if (d < 0) return 0; if (n <= UnivChar(-1)/10 && (n *= 10) <= UnivChar(-1) - d) n += d; } result = n; return 1;}const CatalogEntry *SOEntityCatalog::findBestPublicEntry(const StringC &publicId, Boolean overrideOnly, const CharsetInfo &charset, Boolean &delegated) const{ Char slash = charset.execToDesc('/'); Char colon = charset.execToDesc(':'); const CatalogEntry *bestEntry = 0; for (size_t i = 0; i <= publicId.size(); i++) { if ((i + 1 < publicId.size() && (publicId[i] == slash || publicId[i] == colon) && publicId[i + 1] == publicId[i]) || (i >= 2 && (publicId[i - 1] == slash || publicId[i - 1] == colon) && publicId[i - 2] == publicId[i - 1])) { StringC tem(publicId.data(), i); const CatalogEntry *entry = delegates_.lookup(tem, overrideOnly); if (entry && (!bestEntry || entry->catalogNumber <= bestEntry->catalogNumber)) { bestEntry = entry; delegated = 1; } } } const CatalogEntry *entry = publicIds_.lookup(publicId, overrideOnly); if (entry && (!bestEntry || entry->catalogNumber <= bestEntry->catalogNumber)) { bestEntry = entry; delegated = 0; } return bestEntry;}Boolean SOEntityCatalog::sgmlDecl(const CharsetInfo &charset, Messenger &mgr, StringC &result) const{ return haveSgmlDecl_ && expandCatalogSystemId(sgmlDecl_, sgmlDeclLoc_, sgmlDeclBaseNumber_, 0, charset, 0, mgr, result);}Boolean SOEntityCatalog::document(const CharsetInfo &charset, Messenger &mgr, StringC &result) const{ return haveDocument_ && expandCatalogSystemId(document_, documentLoc_, documentBaseNumber_, 0, charset, 0, mgr, result);}void SOEntityCatalog::addPublicId(StringC &publicId, StringC &systemId, const Location &loc, Boolean override){ CatalogEntry entry; entry.loc = loc; entry.catalogNumber = catalogNumber_; entry.baseNumber = haveCurrentBase_ ? base_.size() : 0; systemId.swap(entry.to); publicIds_.insert(publicId, entry, override);}void SOEntityCatalog::addDelegate(StringC &prefix, StringC &systemId, const Location &loc, Boolean override){ CatalogEntry entry; entry.loc = loc; entry.catalogNumber = catalogNumber_; entry.baseNumber = haveCurrentBase_ ? base_.size() : 0; systemId.swap(entry.to); delegates_.insert(prefix, entry, override);}void SOEntityCatalog::addSystemId(StringC &systemId, StringC &toSystemId, const Location &loc){ CatalogEntry entry; entry.loc = loc; entry.catalogNumber = catalogNumber_; entry.baseNumber = haveCurrentBase_ ? base_.size() : 0; toSystemId.swap(entry.to); systemIds_.insert(systemId, entry, false);}void SOEntityCatalog::addName(StringC &name, DeclType declType, StringC &systemId, const Location &loc, Boolean override){ CatalogEntry entry; entry.loc = loc; entry.catalogNumber = catalogNumber_; entry.baseNumber = haveCurrentBase_ ? base_.size() : 0; int tableIndex = (declType >= EntityDecl::parameterEntity ? int(declType) - 1 : int(declType)); entry.serial = names_[tableIndex].count(); systemId.swap(entry.to); names_[tableIndex].insert(name, entry, override);}void SOEntityCatalog::setSgmlDecl(StringC &str, const Location &loc){ if (!haveSgmlDecl_) { haveSgmlDecl_ = true; str.swap(sgmlDecl_); sgmlDeclLoc_ = loc; sgmlDeclBaseNumber_ = haveCurrentBase_ ? base_.size() : 0; }}void SOEntityCatalog::setDocument(StringC &str, const Location &loc){ if (!haveDocument_) { haveDocument_ = true; str.swap(document_); documentLoc_ = loc; documentBaseNumber_ = haveCurrentBase_ ? base_.size() : 0; }}void SOEntityCatalog::setBase(const Location &loc){ if (loc.origin().isNull()) haveCurrentBase_ = 0; else { haveCurrentBase_ = 1; base_.push_back(loc); }}SOEntityCatalog::Table::Table(){}void SOEntityCatalog::Table::insert(const StringC &key, const CatalogEntry &entry, Boolean override){ if (override) overrideEntries_.insert(key, entry, false); else { const CatalogEntry *e = overrideEntries_.lookup(key); if (!e) normalEntries_.insert(key, entry, false); }}const CatalogEntry *SOEntityCatalog::Table::lookup(const StringC &key, Boolean overrideOnly) const{ if (!overrideOnly) { const CatalogEntry *e = normalEntries_.lookup(key); if (e) return e; } return overrideEntries_.lookup(key);}const CatalogEntry *SOEntityCatalog::Table::lookup(const StringC &name, const SubstTable<Char> &substTable, Boolean overrideOnly) const{ HashTableIter<StringC,CatalogEntry> iter1(overrideEntries_); HashTableIter<StringC,CatalogEntry> iter2(normalEntries_); HashTableIter<StringC,CatalogEntry> *iters[2]; int nIter = 0; iters[nIter++] = &iter1; if (!overrideOnly) iters[nIter++] = &iter2; const CatalogEntry *entry = 0; for (int i = 0; i < nIter; i++) { HashTableIter<StringC,CatalogEntry> &iter = *iters[i]; const StringC *key; const CatalogEntry *value; StringC buffer; while (iter.next(key, value)) { buffer = *key; for (size_t j = 0; j < buffer.size(); j++) substTable.subst(buffer[j]); if (buffer == name) { if (!entry || value->serial < entry->serial) entry = value; } } } return entry;}size_t SOEntityCatalog::Table::count() const{ return normalEntries_.count() + overrideEntries_.count();}CatalogParser::CatalogParser(const CharsetInfo &charset): categoryTable_(data), entityKey_(charset.execToDesc("ENTITY")), publicKey_(charset.execToDesc("PUBLIC")), systemKey_(charset.execToDesc("SYSTEM")), doctypeKey_(charset.execToDesc("DOCTYPE")), linktypeKey_(charset.execToDesc("LINKTYPE")), notationKey_(charset.execToDesc("NOTATION")), overrideKey_(charset.execToDesc("OVERRIDE")), sgmlDeclKey_(charset.execToDesc("SGMLDECL")), documentKey_(charset.execToDesc("DOCUMENT")), catalogKey_(charset.execToDesc("CATALOG")), yesKey_(charset.execToDesc("YES")), noKey_(charset.execToDesc("NO")), baseKey_(charset.execToDesc("BASE")), delegateKey_(charset.execToDesc("DELEGATE")), dtddeclKey_(charset.execToDesc("DTDDECL")), sgmlKey_(charset.execToDesc("SGML")){ static const char lcletters[] = "abcdefghijklmnopqrstuvwxyz"; static const char ucletters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // minimum data other than lcletter, ucletter static const char minChars[] = "0123456789-.'()+,/:=?"; static const char wwwMinChars[] = { 33, 35, 36, 37, 42, 59, 64, 95, 0 }; static const char sChars[] = " \n\r\t"; categoryTable_.setChar(0, nul); const char *p; const char *q; for (p = lcletters, q = ucletters; *p; p++, q++) { Char lc = charset.execToDesc(*p); Char uc = charset.execToDesc(*q);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -