X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FConverterCache.cpp;h=2373b84d2fb06f2fe1ea6ef781aac02fbdef97bc;hb=8f7b40955cc34e31a2932906d334499ef1af3665;hp=4ca2979a35c4581b13a90cf364e884e22a10f4e1;hpb=9383f4c3c6f9cfab2d658701ba66e2b54cd68bea;p=lyx.git diff --git a/src/ConverterCache.cpp b/src/ConverterCache.cpp index 4ca2979a35..2373b84d2f 100644 --- a/src/ConverterCache.cpp +++ b/src/ConverterCache.cpp @@ -22,11 +22,10 @@ #include "support/convert.h" #include "support/debug.h" #include "support/filetools.h" -#include "support/lyxlib.h" #include "support/lyxtime.h" #include "support/Package.h" -#include +#include "support/lassert.h" #include #include @@ -36,53 +35,54 @@ #include using namespace std; +using namespace lyx::support; namespace lyx { -using support::FileName; -using support::addName; - namespace { unsigned long do_crc(string const & s) { boost::crc_32_type crc; - crc = std::for_each(s.begin(), s.end(), crc); + crc = for_each(s.begin(), s.end(), crc); return crc.checksum(); } +// FIXME THREAD +// This should be OK because it is only assigned during init() static FileName cache_dir; class CacheItem { public: - CacheItem() {} + CacheItem() : timestamp(0), checksum(0) {} CacheItem(FileName const & orig_from, string const & to_format, time_t t, unsigned long c) : timestamp(t), checksum(c) { - std::ostringstream os; - os << std::setw(10) << std::setfill('0') << do_crc(orig_from.absFilename()) + ostringstream os; + os << setw(10) << setfill('0') << do_crc(orig_from.absFileName()) << '-' << to_format; - cache_name = FileName(addName(cache_dir.absFilename(), os.str())); + cache_name = FileName(addName(cache_dir.absFileName(), os.str())); LYXERR(Debug::FILES, "Add file cache item " << orig_from << ' ' << to_format << ' ' << cache_name << ' ' << long(timestamp) << ' ' << checksum << '.'); } - ~CacheItem() {} + ~CacheItem() + {} FileName cache_name; time_t timestamp; unsigned long checksum; }; -} +} // namespace /** The cache contains one item per orig file and target format, so use a * nested map to find the cache item quickly by filename and format. */ -typedef std::map FormatCacheType; +typedef map FormatCacheType; class FormatCache { public: /// Format of the source file @@ -90,7 +90,7 @@ public: /// Cache target format -> item to quickly find the item by format FormatCacheType cache; }; -typedef std::map CacheType; +typedef map CacheType; class ConverterCache::Impl { @@ -108,9 +108,9 @@ public: void ConverterCache::Impl::readIndex() { time_t const now = current_time(); - FileName const index(addName(cache_dir.absFilename(), "index")); - std::ifstream is(index.toFilesystemEncoding().c_str()); - Lexer lex(0, 0); + FileName const index(addName(cache_dir.absFileName(), "index")); + ifstream is(index.toFilesystemEncoding().c_str()); + Lexer lex; lex.setStream(is); while (lex.isOK()) { if (!lex.next(true)) @@ -159,7 +159,11 @@ void ConverterCache::Impl::readIndex() FormatCache & format_cache = cache[orig_from_name]; if (format_cache.from_format.empty()) format_cache.from_format = - formats.getFormatFromFile(orig_from_name); + // FIXME perf: This very expensive function is called on all + // cached files on opening. This slows LyX startup a lot. It + // would be better if this information was retrieved in a + // delayed fashion. + theFormats().getFormatFromFile(orig_from_name); format_cache.cache[to_format] = item; } is.close(); @@ -168,10 +172,10 @@ void ConverterCache::Impl::readIndex() void ConverterCache::Impl::writeIndex() { - FileName const index(addName(cache_dir.absFilename(), "index")); - std::ofstream os(index.toFilesystemEncoding().c_str()); + FileName const index(addName(cache_dir.absFileName(), "index")); + ofstream os(index.toFilesystemEncoding().c_str()); os.close(); - if (!lyx::support::chmod(index, 0600)) + if (!index.changePermission(0600)) return; os.open(index.toFilesystemEncoding().c_str()); CacheType::iterator it1 = cache.begin(); @@ -181,7 +185,7 @@ void ConverterCache::Impl::writeIndex() FormatCacheType::const_iterator it2 = format_cache.begin(); FormatCacheType::const_iterator const end2 = format_cache.end(); for (; it2 != end2; ++it2) - os << Lexer::quoteString(it1->first.absFilename()) + os << Lexer::quoteString(it1->first.absFileName()) << ' ' << it2->first << ' ' << it2->second.timestamp << ' ' << it2->second.checksum << '\n'; @@ -219,9 +223,6 @@ ConverterCache::ConverterCache() ConverterCache::~ConverterCache() { - if (!lyxrc.use_converter_cache) - return; - pimpl_->writeIndex(); delete pimpl_; } @@ -240,17 +241,26 @@ void ConverterCache::init() return; // We do this here and not in the constructor because package() gets // initialized after all static variables. - cache_dir = FileName(addName(support::package().user_support().absFilename(), "cache")); + cache_dir = FileName(addName(package().user_support().absFileName(), "cache")); if (!cache_dir.exists()) - if (support::mkdir(cache_dir, 0700) != 0) { + if (!cache_dir.createDirectory(0700)) { lyxerr << "Could not create cache directory `" - << cache_dir << "'." << std::endl; + << cache_dir << "'." << endl; exit(EXIT_FAILURE); } get().pimpl_->readIndex(); } +void ConverterCache::writeIndex() const +{ + if (!lyxrc.use_converter_cache + || cache_dir.empty()) + return; + pimpl_->writeIndex(); +} + + void ConverterCache::add(FileName const & orig_from, string const & to_format, FileName const & converted_file) const { @@ -262,11 +272,11 @@ void ConverterCache::add(FileName const & orig_from, string const & to_format, // FIXME: Should not hardcode this (see bug 3819 for details) if (to_format == "pstex") { - FileName const converted_eps(support::changeExtension(converted_file.absFilename(), "eps")); + FileName const converted_eps(changeExtension(converted_file.absFileName(), "eps")); add(orig_from, "eps", converted_eps); } else if (to_format == "pdftex") { - FileName const converted_pdf(support::changeExtension(converted_file.absFilename(), "pdf")); - add(orig_from, "pdf", converted_pdf); + FileName const converted_pdf(changeExtension(converted_file.absFileName(), "pdf")); + add(orig_from, "pdf6", converted_pdf); } // Is the file in the cache already? @@ -291,19 +301,26 @@ void ConverterCache::add(FileName const & orig_from, string const & to_format, } item->checksum = checksum; if (!mover.copy(converted_file, item->cache_name, - support::onlyFilename(item->cache_name.absFilename()), 0600)) { - LYXERR(Debug::FILES, "ConverterCache::add(" << orig_from << "):\n" - "Could not copy file."); + onlyFileName(item->cache_name.absFileName()))) { + LYXERR(Debug::FILES, "Could not copy file " << orig_from << " to " + << item->cache_name); + } else if (!item->cache_name.changePermission(0600)) { + LYXERR(Debug::FILES, "Could not change file mode" + << item->cache_name); } } else { CacheItem new_item(orig_from, to_format, timestamp, orig_from.checksum()); if (mover.copy(converted_file, new_item.cache_name, - support::onlyFilename(new_item.cache_name.absFilename()), 0600)) { + onlyFileName(new_item.cache_name.absFileName()))) { + if (!new_item.cache_name.changePermission(0600)) { + LYXERR(Debug::FILES, "Could not change file mode" + << new_item.cache_name); + } FormatCache & format_cache = pimpl_->cache[orig_from]; if (format_cache.from_format.empty()) format_cache.from_format = - formats.getFormatFromFile(orig_from); + theFormats().getFormatFromFile(orig_from); format_cache.cache[to_format] = new_item; } else LYXERR(Debug::FILES, "ConverterCache::add(" << orig_from << "):\n" @@ -384,6 +401,20 @@ bool ConverterCache::inCache(FileName const & orig_from, LYXERR(Debug::FILES, "not in cache."); return false; } + + // Special handling of pstex and pdftex formats: These are only + // considered to be in the cache if the corresponding graphics + // fiels are there as well. Otherwise copy() of the graphics below + // would fail. + // FIXME: Should not hardcode this (see bug 3819 for details) + if (to_format == "pstex") { + if (!inCache(orig_from, "eps")) + return false; + } else if (to_format == "pdftex") { + if (!inCache(orig_from, "pdf6")) + return false; + } + time_t const timestamp = orig_from.lastModified(); if (item->timestamp == timestamp) { LYXERR(Debug::FILES, "identical timestamp."); @@ -405,7 +436,7 @@ FileName const & ConverterCache::cacheName(FileName const & orig_from, LYXERR(Debug::FILES, orig_from << ' ' << to_format); CacheItem * const item = pimpl_->find(orig_from, to_format); - BOOST_ASSERT(item); + LASSERT(item, { static const FileName fn; return fn; }); return item->cache_name; } @@ -419,20 +450,20 @@ bool ConverterCache::copy(FileName const & orig_from, string const & to_format, // FIXME: Should not hardcode this (see bug 3819 for details) if (to_format == "pstex") { - FileName const dest_eps(support::changeExtension(dest.absFilename(), "eps")); + FileName const dest_eps(changeExtension(dest.absFileName(), "eps")); if (!copy(orig_from, "eps", dest_eps)) return false; } else if (to_format == "pdftex") { - FileName const dest_pdf(support::changeExtension(dest.absFilename(), "pdf")); - if (!copy(orig_from, "pdf", dest_pdf)) + FileName const dest_pdf(changeExtension(dest.absFileName(), "pdf")); + if (!copy(orig_from, "pdf6", dest_pdf)) return false; } CacheItem * const item = pimpl_->find(orig_from, to_format); - BOOST_ASSERT(item); + LASSERT(item, return false); Mover const & mover = getMover(to_format); return mover.copy(item->cache_name, dest, - support::onlyFilename(dest.absFilename())); + onlyFileName(dest.absFileName())); } } // namespace lyx