/** Loads a cmap and returns the corresponding object. */ CMap* CMapManager::lookup (const string &name) { CMaps::iterator it = _cmaps.find(name); if (it != _cmaps.end()) return it->second; if (_includedCMaps.find(name) != _includedCMaps.end()) { _level = 0; ostringstream oss; oss << "circular reference of CMap " << name; throw CMapReaderException(oss.str()); } CMap *cmap=0; if (name == "Identity-H") cmap = new IdentityHCMap; else if (name == "Identity-V") cmap = new IdentityVCMap; else if (name == "unicode") cmap = new UnicodeCMap; if (cmap) { _cmaps[name] = cmap; return cmap; } // Load cmap data of file <name> and also process all cmaps referenced by operator "usecmap". // This can lead to a sequence of further calls of lookup(). In order to prevent infinite loops // due to (disallowed) circular cmap inclusions, we keep track of all cmaps processed during // a sequence of inclusions. _includedCMaps.insert(name); // save name of current cmap being processed _level++; // increase nesting level try { CMapReader reader; if (!(cmap = reader.read(name))) { _level = 1; Message::wstream(true) << "CMap file '" << name << "' not found\n"; } _cmaps[name] = cmap; } catch (const CMapReaderException &e) { Message::estream(true) << "CMap file " << name << ": " << e.what() << "\n"; } if (--_level == 0) // back again at initial nesting level? _includedCMaps.clear(); // => names of included cmaps are no longer needed return cmap; }
CMapReaderTest () { istringstream iss(cmapsrc); CMapReader reader; cmap = reader.read(iss, "Test-Map"); }