Boolean FSIParser::convertId(StringC &id, Xchar smcrd, const StorageManager *sm) { const CharsetInfo *smCharset = sm->idCharset(); StringC newId; size_t i = 0; while (i < id.size()) { UnivChar univ; WideChar wide; ISet<WideChar> wideSet; int digit; if (Xchar(id[i]) == smcrd && i + 1 < id.size() && convertDigit(id[i + 1], digit)) { i += 2; Char val = digit; while (i < id.size() && convertDigit(id[i], digit)) { val = val*10 + digit; i++; } newId += val; if (i < id.size() && matchChar(id[i], ';')) i++; } else if (smCharset) { if (!idCharset_.descToUniv(id[i++], univ)) return 0; if (univ == UnivCharsetDesc::rs) ; else if (univ == UnivCharsetDesc::re && sm->reString()) newId += *sm->reString(); else if (smCharset->univToDesc(univ, wide, wideSet) != 1 || wide > charMax) return 0; // FIXME give error else newId += Char(wide); } else newId += id[i++]; } newId.swap(id); return 1; }
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; }