📄 extendentitymanager.cxx
字号:
// Copyright (c) 1994, 1995, 1996 James Clark// See the file COPYING for copying permission.#ifdef __GNUG__#pragma implementation#endif#include "splib.h"#include "ExtendEntityManager.h"#include "Message.h"#include "MessageArg.h"#include "OffsetOrderedList.h"#include "rtti.h"#include "StorageManager.h"#include "Vector.h"#include "NCVector.h"#include "Owner.h"#include "constant.h"#include "EntityManagerMessages.h"#include "StorageObjectPosition.h"#include "Owner.h"#include "CodingSystem.h"#include "CodingSystemKit.h"#include "InputSource.h"#include "Mutex.h"#include "macros.h"#include "EntityCatalog.h"#include "CharMap.h"#include <stddef.h>#include <string.h>#include <stdlib.h>#include <ctype.h>#include <stdio.h>#ifdef DECLARE_MEMMOVEextern "C" { void *memmove(void *, const void *, size_t);}#endif#ifdef SP_NAMESPACEnamespace SP_NAMESPACE {#endifconst char EOFCHAR = '\032'; // Control-Zclass ExternalInputSource;class EntityManagerImpl : public ExtendEntityManager {public: EntityManagerImpl(StorageManager *defaultStorageManager, const InputCodingSystem *defaultCodingSystem, const ConstPtr<InputCodingSystemKit> &, Boolean internalCharsetIsDocCharset); void setCatalogManager(CatalogManager *catalogManager); void registerStorageManager(StorageManager *); InputSource *open(const StringC &sysid, const CharsetInfo &, InputSourceOrigin *, unsigned flags, Messenger &); const CharsetInfo &charset() const; Boolean internalCharsetIsDocCharset() const; ConstPtr<EntityCatalog> makeCatalog(StringC &systemId, const CharsetInfo &charset, Messenger &mgr); Boolean expandSystemId(const StringC &, const Location &, Boolean isNdata, const CharsetInfo &, const StringC *, Messenger &, StringC &); Boolean mergeSystemIds(const Vector<StringC> &, Boolean mapCatalogDocument, const CharsetInfo &, Messenger &mgr, StringC &) const; StorageManager *lookupStorageType(const StringC &, const CharsetInfo &) const; StorageManager *lookupStorageType(const char *) const; StorageManager *guessStorageType(const StringC &, const CharsetInfo &) const; const InputCodingSystem *lookupCodingSystem(const StringC &, const CharsetInfo &, Boolean isBctf, const char *&) const; Boolean resolveSystemId(const StringC &str, const CharsetInfo &idCharset, Messenger &mgr, const Location &defLocation, Boolean isNdata, ParsedSystemId &parsedSysid) const; Boolean parseSystemId(const StringC &str, const CharsetInfo &idCharset, Boolean isNdata, const StorageObjectLocation *def, Messenger &mgr, ParsedSystemId &parsedSysid) const; const CharsetInfo &internalCharset(const CharsetInfo &docCharset) const { if (internalCharsetIsDocCharset_) return docCharset; else return charset(); }private: EntityManagerImpl(const EntityManagerImpl &); // undefined void operator=(const EntityManagerImpl &); // undefined static Boolean defLocation(const Location &, StorageObjectLocation &); static Boolean matchKey(const StringC &type, const char *s, const CharsetInfo &internalCharset); NCVector<Owner<StorageManager> > storageManagers_; Owner<StorageManager> defaultStorageManager_; const InputCodingSystem *defaultCodingSystem_; Owner<CatalogManager> catalogManager_; Boolean internalCharsetIsDocCharset_; ConstPtr<InputCodingSystemKit> codingSystemKit_; friend class FSIParser;};class ExternalInfoImpl : public ExternalInfo { RTTI_CLASSpublic: ExternalInfoImpl(ParsedSystemId &parsedSysid); const StorageObjectSpec &spec(size_t i) const; size_t nSpecs() const; const ParsedSystemId &parsedSystemId() const; void noteRS(Offset); void noteStorageObjectEnd(Offset); void noteInsertedRSs(); void setDecoder(size_t i, Decoder *); void setId(size_t i, StringC &); void getId(size_t i, StringC &) const; Boolean convertOffset(Offset, StorageObjectLocation &) const;private: ParsedSystemId parsedSysid_; NCVector<StorageObjectPosition> position_; size_t currentIndex_; // list of inserted RSs OffsetOrderedList rsList_; Boolean notrack_; Mutex mutex_;};class ExternalInputSource : public InputSource {public: ExternalInputSource(ParsedSystemId &parsedSysid, const CharsetInfo &internalCharset, const CharsetInfo &docCharset, Boolean internalCharsetIsDocCharset, Char replacementChar, InputSourceOrigin *origin, unsigned flags); void pushCharRef(Char, const NamedCharRef &); ~ExternalInputSource();private: Xchar fill(Messenger &); Boolean rewind(Messenger &); void willNotRewind(); void setDocCharset(const CharsetInfo &, const CharsetInfo &); void willNotSetDocCharset(); void init(); void noteRS(); void noteRSAt(const Char *); void reallocateBuffer(size_t size); void insertChar(Char); void buildMap(const CharsetInfo &internalCharset, const CharsetInfo &docCharset); void buildMap1(const CharsetInfo &, const CharsetInfo &); static const Char *findNextCr(const Char *start, const Char *end); static const Char *findNextLf(const Char *start, const Char *end); static const Char *findNextCrOrLf(const Char *start, const Char *end); ExternalInfoImpl *info_; Char *buf_; const Char *bufLim_; Offset bufLimOffset_; size_t bufSize_; size_t readSize_; NCVector<Owner<StorageObject> > sov_; StorageObject *so_; size_t soIndex_; Boolean insertRS_; Decoder *decoder_; const char *leftOver_; size_t nLeftOver_; Boolean mayRewind_; Boolean maySetDocCharset_; Boolean mayNotExist_; enum RecordType { unknown, crUnknown, crlf, lf, cr, asis }; RecordType recordType_; Boolean zapEof_; Boolean internalCharsetIsDocCharset_; Char replacementChar_; Ptr<CharMapResource<Unsigned32> > map_;};class FSIParser {public: FSIParser(const StringC &, const CharsetInfo &idCharset, Boolean isNdata, const StorageObjectLocation *defLoc, const EntityManagerImpl *em, Messenger &mgr); Boolean parse(ParsedSystemId &parsedSysid); static const char *recordsName(StorageObjectSpec::Records records); struct RecordType { const char *name; StorageObjectSpec::Records value; };private: Boolean handleInformal(size_t startIndex, ParsedSystemId &parsedSysid); Boolean convertId(StringC &, Xchar smcrd, const StorageManager *); Xchar get(); void unget(); StorageManager *lookupStorageType(const StringC &key, Boolean &neutral); Boolean matchKey(const StringC &, const char *); Boolean matchChar(Xchar, char); Boolean isS(Xchar); Boolean convertDigit(Xchar c, int &weight); void uncharref(StringC &); Boolean setAttributes(StorageObjectSpec &sos, Boolean neutral, Xchar &smcrd, Boolean &fold); Boolean setCatalogAttributes(ParsedSystemId &parsedSysid); void setDefaults(StorageObjectSpec &sos); Boolean parseAttribute(StringC &token, Boolean &gotValue, StringC &value); Boolean lookupRecords(const StringC &token, StorageObjectSpec::Records &); void convertMinimumLiteral(const StringC &from, StringC &to); const StringC &str_; size_t strIndex_; Messenger &mgr_; const EntityManagerImpl *em_; const StorageObjectSpec *defSpec_; const StringC *defId_; const CharsetInfo &idCharset_; Boolean isNdata_; static RecordType recordTypeTable[];};const Char RS = '\n';const Char RE = '\r';ExtendEntityManager::CatalogManager::~CatalogManager(){}ExtendEntityManager *ExtendEntityManager::make(StorageManager *sm, const InputCodingSystem *cs, const ConstPtr<InputCodingSystemKit> &csKit, Boolean internalCharsetIsDocCharset){ return new EntityManagerImpl(sm, cs, csKit, internalCharsetIsDocCharset);}Boolean ExtendEntityManager::externalize(const ExternalInfo *info, Offset off, StorageObjectLocation &loc){ if (!info) return false; const ExternalInfoImpl *p = DYNAMIC_CAST_CONST_PTR(ExternalInfoImpl, info); if (!p) return false; return p->convertOffset(off, loc);}const ParsedSystemId *ExtendEntityManager::externalInfoParsedSystemId(const ExternalInfo *info){ if (!info) return 0; const ExternalInfoImpl *p = DYNAMIC_CAST_CONST_PTR(ExternalInfoImpl, info); if (!p) return 0; return &p->parsedSystemId();}EntityManagerImpl::EntityManagerImpl(StorageManager *defaultStorageManager, const InputCodingSystem *defaultCodingSystem, const ConstPtr<InputCodingSystemKit> &codingSystemKit, Boolean internalCharsetIsDocCharset): defaultStorageManager_(defaultStorageManager), defaultCodingSystem_(defaultCodingSystem), codingSystemKit_(codingSystemKit), internalCharsetIsDocCharset_(internalCharsetIsDocCharset){}Boolean EntityManagerImpl::internalCharsetIsDocCharset() const{ return internalCharsetIsDocCharset_;}const CharsetInfo &EntityManagerImpl::charset() const{ return codingSystemKit_->systemCharset();}InputSource *EntityManagerImpl::open(const StringC &sysid, const CharsetInfo &docCharset, InputSourceOrigin *origin, unsigned flags, Messenger &mgr){ ParsedSystemId parsedSysid; if (!parseSystemId(sysid, docCharset, (flags & ExtendEntityManager::isNdata) != 0, 0, mgr, parsedSysid) || !catalogManager_->mapCatalog(parsedSysid, this, mgr)) return 0; return new ExternalInputSource(parsedSysid, charset(), docCharset, internalCharsetIsDocCharset_, codingSystemKit_->replacementChar(), origin, flags);}ConstPtr<EntityCatalog>EntityManagerImpl::makeCatalog(StringC &systemId, const CharsetInfo &docCharset, Messenger &mgr){ return catalogManager_->makeCatalog(systemId, docCharset, this, mgr);}BooleanEntityManagerImpl::mergeSystemIds(const Vector<StringC> &sysids, Boolean mapCatalogDocument, const CharsetInfo &docCharset, Messenger &mgr, StringC &result) const{ ParsedSystemId parsedSysid; if (mapCatalogDocument) { parsedSysid.maps.resize(parsedSysid.maps.size() + 1); parsedSysid.maps.back().type = ParsedSystemId::Map::catalogDocument; } for (size_t i = 0; i < sysids.size(); i++) if (!parseSystemId(sysids[i], docCharset, 0, 0, mgr, parsedSysid)) return 0; parsedSysid.unparse(internalCharset(docCharset), 0, result); return 1;}BooleanEntityManagerImpl::expandSystemId(const StringC &str, const Location &defLoc, Boolean isNdata, const CharsetInfo &docCharset, const StringC *mapCatalogPublic, Messenger &mgr, StringC &result){ ParsedSystemId parsedSysid; StorageObjectLocation defSoLoc; const StorageObjectLocation *defSoLocP; if (defLocation(defLoc, defSoLoc)) defSoLocP = &defSoLoc; else defSoLocP = 0; if (!parseSystemId(str, docCharset, isNdata, defSoLocP, mgr, parsedSysid)) return 0; if (mapCatalogPublic) { ParsedSystemId::Map map; map.type = ParsedSystemId::Map::catalogPublic; map.publicId = *mapCatalogPublic; parsedSysid.maps.insert(parsedSysid.maps.begin(), 1, map); } parsedSysid.unparse(internalCharset(docCharset), isNdata, result); return 1;}Boolean EntityManagerImpl::parseSystemId(const StringC &str, const CharsetInfo &docCharset, Boolean isNdata, const StorageObjectLocation *defLoc, Messenger &mgr, ParsedSystemId &parsedSysid) const{ FSIParser fsiParser(str, internalCharset(docCharset), isNdata, defLoc, this, mgr); return fsiParser.parse(parsedSysid);}StorageManager *EntityManagerImpl::guessStorageType(const StringC &type, const CharsetInfo &internalCharset) const{ for (size_t i = 0; i < storageManagers_.size(); i++) if (storageManagers_[i]->guessIsId(type, internalCharset)) return storageManagers_[i].pointer(); if (defaultStorageManager_->guessIsId(type, internalCharset)) return defaultStorageManager_.pointer(); return 0;}StorageManager *EntityManagerImpl::lookupStorageType(const StringC &type, const CharsetInfo &internalCharset) const{ if (type.size() == 0) return 0; if (matchKey(type, defaultStorageManager_->type(), internalCharset)) return defaultStorageManager_.pointer(); for (size_t i = 0; i < storageManagers_.size(); i++) if (matchKey(type, storageManagers_[i]->type(), internalCharset)) return storageManagers_[i].pointer(); return 0;}StorageManager *EntityManagerImpl::lookupStorageType(const char *type) const{ if (type == defaultStorageManager_->type()) return defaultStorageManager_.pointer(); for (size_t i = 0; i < storageManagers_.size(); i++) if (type == storageManagers_[i]->type()) return storageManagers_[i].pointer(); return 0;}const InputCodingSystem *EntityManagerImpl::lookupCodingSystem(const StringC &type, const CharsetInfo &internalCharset, Boolean isBctf, const char *&name) const{ return codingSystemKit_->makeInputCodingSystem(type, internalCharset, isBctf, name);}BooleanEntityManagerImpl::matchKey(const StringC &type, const char *s, const CharsetInfo &internalCharset){ if (strlen(s) != type.size()) return false; for (size_t i = 0; i < type.size(); i++) if (internalCharset.execToDesc(toupper(s[i])) != type[i] && internalCharset.execToDesc(tolower(s[i])) != type[i]) return false; return true;}void EntityManagerImpl::registerStorageManager(StorageManager *sm){ storageManagers_.resize(storageManagers_.size() + 1); storageManagers_.back() = sm;}void EntityManagerImpl::setCatalogManager(CatalogManager *catalogManager){ catalogManager_ = catalogManager;}BooleanEntityManagerImpl::defLocation(const Location &defLocation, StorageObjectLocation &soLoc){ Offset off; const ExternalInfo *info; const Origin *origin = defLocation.origin().pointer(); Index index = defLocation.index(); for (;;) { if (!origin) return 0; const InputSourceOrigin *inputSourceOrigin = origin->asInputSourceOrigin(); if (inputSourceOrigin) { off = inputSourceOrigin->startOffset(index); info = inputSourceOrigin->externalInfo(); if (info) break; if (!inputSourceOrigin->defLocation(off, origin, index)) return 0; } else { const Location &parentLoc = origin->parent(); origin = parentLoc.origin().pointer(); index = parentLoc.index(); } } return ExtendEntityManager::externalize(info, off, soLoc);}class UnbufferingStorageObject : public StorageObject {public: UnbufferingStorageObject(StorageObject *sub, const Boolean *unbuffer) : sub_(sub), buf_(0), bufAvail_(0), bufNext_(0), unbuffer_(unbuffer) { } ~UnbufferingStorageObject() { delete [] buf_; } Boolean read(char *buf, size_t bufSize, Messenger &mgr, size_t &nread) { if (bufNext_ >= bufAvail_) { bufAvail_ = bufNext_ = 0; if (!*unbuffer_) return sub_->read(buf, bufSize, mgr, nread); if (buf_ == 0) buf_ = new char[bufSize_ = bufSize]; if (!sub_->read(buf_, bufSize_, mgr, bufAvail_)) return 0; } *buf = buf_[bufNext_++]; nread = 1; return 1; } Boolean rewind(Messenger &mgr) { bufAvail_ = bufNext_ = 0; return sub_->rewind(mgr); } void willNotRewind() { sub_->willNotRewind(); } size_t getBlockSize() const { return sub_->getBlockSize(); }private: Owner<StorageObject> sub_; size_t bufSize_; size_t bufAvail_; size_t bufNext_; char *buf_; const Boolean *unbuffer_;};class MappingDecoder : public Decoder {public: MappingDecoder(Decoder *, const ConstPtr<CharMapResource<Unsigned32> > &); Boolean convertOffset(unsigned long &offset) const;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -