📄 extendentitymanager.cxx
字号:
{ Char *newBuf = new Char[newSize]; memcpy(newBuf, buf_, bufSize_*sizeof(Char)); bufSize_ = newSize; changeBuffer(newBuf, buf_); bufLim_ = newBuf + (bufLim_ - buf_); if (nLeftOver_ > 0) { char *s = (char *)(newBuf + bufSize_) - nLeftOver_; memmove(s, (char *)newBuf + (leftOver_ - (char *)buf_), nLeftOver_); leftOver_ = s; } delete [] buf_; buf_ = newBuf;}RTTI_DEF1(ExternalInfoImpl, ExternalInfo)ExternalInfoImpl::ExternalInfoImpl(ParsedSystemId &parsedSysid): currentIndex_(0), position_(parsedSysid.size()){ parsedSysid.swap(parsedSysid_); if (parsedSysid_.size() > 0) notrack_ = parsedSysid_[0].notrack;}void ExternalInfoImpl::setId(size_t i, StringC &id){ Mutex::Lock lock(&mutex_); id.swap(position_[i].id);}void ExternalInfoImpl::getId(size_t i, StringC &id) const{ Mutex::Lock lock(&((ExternalInfoImpl *)this)->mutex_); id = position_[i].id;}void ExternalInfoImpl::setDecoder(size_t i, Decoder *decoder){ Mutex::Lock lock(&mutex_); position_[i].decoder = decoder;}void ExternalInfoImpl::noteInsertedRSs(){ position_[currentIndex_].insertedRSs = 1;}void ExternalInfoImpl::noteRS(Offset offset){ // We do the locking in OffsetOrderedList. if (!notrack_) rsList_.append(offset); if (offset == (currentIndex_ == 0 ? 0 : position_[currentIndex_- 1].endOffset)) position_[currentIndex_].startsWithRS = 1;}void ExternalInfoImpl::noteStorageObjectEnd(Offset offset){ Mutex::Lock lock(&mutex_); ASSERT(currentIndex_ < position_.size()); // The last endOffset_ must be -1. if (currentIndex_ < position_.size() - 1) { position_[currentIndex_++].endOffset = offset; position_[currentIndex_].line1RS = rsList_.size(); notrack_ = parsedSysid_[currentIndex_].notrack; }}Boolean ExternalInfoImpl::convertOffset(Offset off, StorageObjectLocation &ret) const{ Mutex::Lock lock(&((ExternalInfoImpl *)this)->mutex_); if (off == Offset(-1) || position_.size() == 0) return false; // the last endOffset_ is Offset(-1), so this will // terminate int i; for (i = 0; off >= position_[i].endOffset; i++) ; for (; position_[i].id.size() == 0; i--) if (i == 0) return false; ret.storageObjectSpec = &parsedSysid_[i]; ret.actualStorageId = position_[i].id; Offset startOffset = i == 0 ? 0 : position_[i - 1].endOffset; ret.storageObjectOffset = off - startOffset; ret.byteIndex = ret.storageObjectOffset; if (parsedSysid_[i].notrack || parsedSysid_[i].records == StorageObjectSpec::asis) { ret.lineNumber = (unsigned long)-1; if (parsedSysid_[i].records != StorageObjectSpec::asis) { if (position_[i].insertedRSs) ret.byteIndex = (unsigned long)-1; else if (ret.byteIndex > 0 && position_[i].startsWithRS) ret.byteIndex--; // first RS is inserted } ret.columnNumber = (unsigned long)-1; return true; } else { size_t line1RS = position_[i].line1RS; // line1RS is now the number of RSs that are before or on the current line. size_t j; Offset colStart; if (rsList_.findPreceding(off, j, colStart)) { if (position_[i].insertedRSs) ret.byteIndex -= j + 1 - line1RS; else if (ret.byteIndex > 0 && position_[i].startsWithRS) ret.byteIndex--; // first RS is inserted j++; colStart++; } else { j = 0; colStart = 0; } // j is now the number of RSs that are before or on the current line // colStart is the offset of the first column ret.lineNumber = j - line1RS + 1 - position_[i].startsWithRS; // the offset of the first column if (colStart < startOffset) colStart = startOffset; // the RS that starts a line will be in column 0; // the first real character of a line will be column 1 ret.columnNumber = 1 + off - colStart; } if (!position_[i].decoder || !position_[i].decoder->convertOffset(ret.byteIndex)) ret.byteIndex = (unsigned long)-1; return true;}const StorageObjectSpec &ExternalInfoImpl::spec(size_t i) const{ return parsedSysid_[i];}size_t ExternalInfoImpl::nSpecs() const{ return parsedSysid_.size();}const ParsedSystemId &ExternalInfoImpl::parsedSystemId() const{ return parsedSysid_;}StorageObjectSpec::StorageObjectSpec(): storageManager(0), codingSystem(0), codingSystemName(0), notrack(0), records(find), zapEof(1), search(1){}StorageObjectPosition::StorageObjectPosition(): endOffset(Offset(-1)), line1RS(0), startsWithRS(0), insertedRSs(0){}FSIParser::FSIParser(const StringC &str, const CharsetInfo &idCharset, Boolean isNdata, const StorageObjectLocation *defLoc, const EntityManagerImpl *em, Messenger &mgr): str_(str), strIndex_(0), idCharset_(idCharset), isNdata_(isNdata), defSpec_(defLoc ? defLoc->storageObjectSpec : 0), defId_(defLoc ? &defLoc->actualStorageId : 0), em_(em), mgr_(mgr){}Xchar FSIParser::get(){ if (strIndex_ < str_.size()) return str_[strIndex_++]; else return -1;}void FSIParser::unget(){ if (strIndex_ > 0) strIndex_ -= 1;}Boolean FSIParser::matchKey(const StringC &str, const char *s){ if (strlen(s) != str.size()) return false; for (size_t i = 0; i < str.size(); i++) if (idCharset_.execToDesc(toupper(s[i])) != str[i] && idCharset_.execToDesc(tolower(s[i])) != str[i]) return false; return true;}Boolean FSIParser::matchChar(Xchar ch, char execC){ return ch == idCharset_.execToDesc(execC);}Boolean FSIParser::isS(Xchar c){ return (matchChar(c, ' ') || matchChar(c, '\r') || matchChar(c, '\n') || matchChar(c, ' '));}Boolean FSIParser::convertDigit(Xchar c, int &weight){ static const char digits[] = "0123456789"; for (int i = 0; digits[i] != '\0'; i++) if (matchChar(c, digits[i])) { weight = i; return 1; } return 0;}Boolean FSIParser::parse(ParsedSystemId &parsedSysid){ size_t startIndex = strIndex_; if (!matchChar(get(), '<')) return handleInformal(startIndex, parsedSysid); StringC key; for (;;) { Xchar c = get(); if (c == -1) return handleInformal(startIndex, parsedSysid); if (isS(c) || matchChar(c, '>')) break; key += Char(c); } unget(); if (matchKey(key, "CATALOG")) { if (!setCatalogAttributes(parsedSysid)) return 0; return parse(parsedSysid); } Boolean neutral; StorageManager *sm = lookupStorageType(key, neutral); if (!sm) return handleInformal(startIndex, parsedSysid); for (;;) { parsedSysid.resize(parsedSysid.size() + 1); StorageObjectSpec &sos = parsedSysid.back(); sos.storageManager = sm; Xchar smcrd; Boolean fold; if (!setAttributes(sos, neutral, smcrd, fold)) return 0; sm = 0; StringC id; Boolean hadData = 0; for (;;) { Xchar c = get(); if (c == -1) break; if (matchChar(c, '<')) { hadData = 1; Char stago = c; key.resize(0); for (;;) { c = get(); if (c == -1) { id += stago; id += key; break; } if (isS(c) || matchChar(c, '>')) { unget(); sm = lookupStorageType(key, neutral); if (!sm) { id += stago; id += key; } break; } key += c; } if (sm) break; } else if (!((!hadData && matchChar(c, '\r')) // ignored RE || matchChar(c, '\n') )) { // ignored RS hadData = 1; id += c; } } if (id.size() > 0 && matchChar(id[id.size() - 1], '\r')) id.resize(id.size() - 1); uncharref(id); id.swap(sos.specId); if (!convertId(sos.specId, smcrd, sos.storageManager)) return 0; if (neutral) { if (!sos.storageManager->transformNeutral(sos.specId, fold, mgr_)) return 0; } if (sos.storageManager->resolveRelative(sos.baseId, sos.specId, sos.search)) sos.baseId.resize(0); if (!sm) break; } return 1;}Boolean FSIParser::handleInformal(size_t index, ParsedSystemId &parsedSysid){ parsedSysid.resize(parsedSysid.size() + 1); StorageObjectSpec &sos = parsedSysid.back(); sos.specId.assign(str_.data() + index, str_.size() - index); sos.storageManager = em_->guessStorageType(sos.specId, idCharset_); if (!sos.storageManager) { if (defSpec_ && defSpec_->storageManager->inheritable()) sos.storageManager = defSpec_->storageManager; else sos.storageManager = em_->defaultStorageManager_.pointer(); } setDefaults(sos); if (!convertId(sos.specId, -1, sos.storageManager)) return 0; if (sos.storageManager->resolveRelative(sos.baseId, sos.specId, sos.search)) sos.baseId.resize(0); return 1;}StorageManager *FSIParser::lookupStorageType(const StringC &key, Boolean &neutral){ if (matchKey(key, "NEUTRAL")) { neutral = 1; if (defSpec_ && defSpec_->storageManager->inheritable()) return defSpec_->storageManager; else return em_->defaultStorageManager_.pointer(); } else { StorageManager *sm = em_->lookupStorageType(key, idCharset_); if (sm) neutral = 0; return sm; }}Boolean FSIParser::setCatalogAttributes(ParsedSystemId &parsedSysid){ Boolean hadPublic = 0; parsedSysid.maps.resize(parsedSysid.maps.size() + 1); parsedSysid.maps.back().type = ParsedSystemId::Map::catalogDocument; for (;;) { StringC token, value; Boolean gotValue; if (!parseAttribute(token, gotValue, value)) { mgr_.message(EntityManagerMessages::fsiSyntax, StringMessageArg(str_)); return 0; } if (token.size() == 0) break; if (matchKey(token, "PUBLIC")) { if (hadPublic) mgr_.message(EntityManagerMessages::fsiDuplicateAttribute, StringMessageArg(idCharset_.execToDesc("PUBLIC"))); else if (gotValue) { convertMinimumLiteral(value, parsedSysid.maps.back().publicId); parsedSysid.maps.back().type = ParsedSystemId::Map::catalogPublic; } else mgr_.message(EntityManagerMessages::fsiMissingValue, StringMessageArg(token)); hadPublic = 1; } else mgr_.message(gotValue ? EntityManagerMessages::fsiUnsupportedAttribute : EntityManagerMessages::fsiUnsupportedAttributeToken, StringMessageArg(token)); } return 1;}void FSIParser::convertMinimumLiteral(const StringC &from, StringC &to){ // Do just enough to ensure it can be reparsed. to.resize(0); for (size_t i = 0; i < from.size(); i++) { Char c = from[i]; if (matchChar(c, '"') || matchChar(c, '#')) mgr_.message(EntityManagerMessages::fsiLookupChar, NumberMessageArg(c)); else if (matchChar(c, ' ')) { if (to.size() && to[to.size() - 1] != c) to += c; } else to += c; } if (to.size() && matchChar(to[to.size() - 1], ' ')) to.resize(to.size() - 1);}// FIXME This should be table driven.Boolean FSIParser::setAttributes(StorageObjectSpec &sos, Boolean neutral, Xchar &smcrd, Boolean &fold){ Boolean hadBctf = 0; Boolean hadEncoding = 0; Boolean hadTracking = 0; Boolean hadSmcrd = 0; smcrd = -1; fold = 1; Boolean hadRecords = 0; Boolean hadBase = 0; Boolean hadZapeof = 0; Boolean hadSearch = 0; Boolean hadFold = 0; StorageObjectSpec::Records records; setDefaults(sos); for (;;) { StringC token, value; Boolean gotValue; if (!parseAttribute(token, gotValue, value)) { mgr_.message(EntityManagerMessages::fsiSyntax, StringMessageArg(str_)); return 0; } if (token.size() == 0) break; if (matchKey(token, "BCTF")) { if (sos.storageManager->requiredCodingSystem()) mgr_.message(EntityManagerMessages::fsiBctfEncodingNotApplicable); else if (hadBctf) mgr_.message(EntityManagerMessages::fsiDuplicateAttribute, StringMessageArg(token)); else if (hadEncoding) mgr_.message(EntityManagerMessages::fsiBctfAndEncoding); else if (gotValue) { const char *codingSystemName; const InputCodingSystem *codingSystem = em_->lookupCodingSystem(value, idCharset_, 1, codingSystemName); if (codingSystem) { sos.codingSystem = codingSystem; sos.codingSystemName = codingSystemName; sos.codingSystemType = StorageObjectSpec::bctf; } else if (matchKey(value, "SAME")) { if (!isNdata_) { if (defSpec_) { sos.codingSystem = defSpec_->codingSystem; sos.codingSystemName = defSpec_->codingSystemName; sos.codingSystemType = defSpec_->codingSystemType; } else { sos.codingSystem = em_->defaultCodingSystem_; sos.codingSystemName = 0; sos.codingSystemType = (em_->internalCharsetIsDocCharset_ ? StorageObjectSpec::bctf : StorageObjectSpec::encoding); } } } else mgr_.message(EntityManagerMessages::fsiUnknownBctf, StringMessageArg(value)); } else mgr_.message(EntityManagerMessages::fsiMissingValue, StringMessageArg(token)); hadBctf = 1; } else if (matchKey(token, "ENCODING")) { if (sos.storageManager->requiredCodingSystem()) mgr_.message(EntityManagerMessages::fsiBctfEncodingNotApplicable); else if (hadEncoding) mgr_.message(EntityManagerMessages::fsiDuplicateAttribute, StringMessageArg(token)); else if (hadBctf) mgr_.message(EntityManagerMessages::fsiBctfAndEncoding); else if (gotValue) { const char *codingSystemName; const InputCodingSystem *codingSystem = em_->lookupCodingSystem(value, idCharset_, 0, codingSystemName); if (codingSystem) { sos.codingSystem = codingSystem; sos.codingSystemName = codingSystemName; sos.codingSystemType = StorageObjectSpec::encoding; } else if (matchKey(value, "SAME")) { if (!isNdata_) { if (defSpec_) { sos.codingSystem = defSpec_->codingSystem; sos.codingSystemName = defSpec_->codingSystemName; sos.codingSystemType = defSpec_->codingSystemType; } else { sos.codingSystem = em_->defaultCodingSystem_; sos.codingSystemName = 0; sos.codingSystemType = (em_->internalCharsetIsDocCharset_ ? StorageObjectSpec::bctf : StorageObjectSpec::encoding); } } } else mgr_.message(EntityManagerMessages::fsiUnknownEncoding, StringMessageArg(value)); } else mgr_.message(EntityManagerMessages::fsiMissingValue, StringMessageArg(token)); hadEncoding = 1; } else if (matchKey(token, "TRACKING")) { if (hadTracking) mgr_.message(EntityManagerMessages::fsiDuplicateAttribute, StringMessageArg(token)); else if (gotValue) { if (matchKey(value, "NOTRACK")) sos.notrack = 1; else if (!matchKey(value, "TRACK")) mgr_.message(EntityManagerMessages::fsiBadTracking, StringMessageArg(value)); } else mgr_.message(EntityManagerMessages::fsiMissingValue,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -