#include "ConverterCache.h"
-#include "debug.h"
+#include "Format.h"
+#include "Lexer.h"
#include "LyXRC.h"
#include "Mover.h"
+#include "debug.h"
+#include "support/convert.h"
#include "support/filetools.h"
#include "support/lyxlib.h"
#include "support/lyxtime.h"
public:
CacheItem() {}
CacheItem(FileName const & orig_from, string const & to_format,
- time_t t, unsigned long c)
+ time_t t, unsigned long c)
: timestamp(t), checksum(c)
{
std::ostringstream os;
<< '-' << to_format;
cache_name = FileName(addName(cache_dir.absFilename(), os.str()));
LYXERR(Debug::FILES) << "Add file cache item " << orig_from
- << ' ' << to_format << ' ' << cache_name
- << ' ' << timestamp << ' ' << checksum
- << '.' << std::endl;
+ << ' ' << to_format << ' ' << cache_name
+ << ' ' << timestamp << ' ' << checksum
+ << '.' << std::endl;
}
~CacheItem() {}
FileName cache_name;
* nested map to find the cache item quickly by filename and format.
*/
typedef std::map<string, CacheItem> FormatCacheType;
-typedef std::map<FileName, FormatCacheType> CacheType;
+class FormatCache {
+public:
+ /// Format of the source file
+ string from_format;
+ /// Cache target format -> item to quickly find the item by format
+ FormatCacheType cache;
+};
+typedef std::map<FileName, FormatCache> CacheType;
class ConverterCache::Impl {
time_t const now = current_time();
FileName const index(addName(cache_dir.absFilename(), "index"));
std::ifstream is(index.toFilesystemEncoding().c_str());
- while (is.good()) {
- string orig_from;
- string to_format;
- time_t timestamp;
- unsigned long checksum;
- if (!(is >> orig_from >> to_format >> timestamp >> checksum))
- return;
+ Lexer lex(0, 0);
+ lex.setStream(is);
+ while (lex.isOK()) {
+ if (!lex.next(true))
+ break;
+ string const orig_from = lex.getString();
+ if (!lex.next())
+ break;
+ string const to_format = lex.getString();
+ if (!lex.next())
+ break;
+ time_t const timestamp =
+ convert<unsigned long>(lex.getString());
+ if (!lex.next())
+ break;
+ unsigned long const checksum =
+ convert<unsigned long>(lex.getString());
FileName const orig_from_name(orig_from);
CacheItem item(orig_from_name, to_format, timestamp, checksum);
continue;
}
- cache[orig_from_name][to_format] = item;
+ FormatCache & format_cache = cache[orig_from_name];
+ if (format_cache.from_format.empty())
+ format_cache.from_format =
+ formats.getFormatFromFile(orig_from_name);
+ format_cache.cache[to_format] = item;
}
is.close();
}
CacheType::iterator it1 = cache.begin();
CacheType::iterator const end1 = cache.end();
for (; it1 != end1; ++it1) {
- FormatCacheType::iterator it2 = it1->second.begin();
- FormatCacheType::iterator const end2 = it1->second.end();
+ FormatCacheType const & format_cache = it1->second.cache;
+ FormatCacheType::const_iterator it2 = format_cache.begin();
+ FormatCacheType::const_iterator const end2 = format_cache.end();
for (; it2 != end2; ++it2)
- os << it1->first << ' ' << it2->first << ' '
+ os << Lexer::quoteString(it1->first.absFilename())
+ << ' ' << it2->first << ' '
<< it2->second.timestamp << ' '
<< it2->second.checksum << '\n';
}
CacheType::iterator const it1 = cache.find(from);
if (it1 == cache.end())
return 0;
- FormatCacheType::iterator const it2 = it1->second.find(format);
- if (it2 == it1->second.end())
+ FormatCacheType & format_cache = it1->second.cache;
+ FormatCacheType::iterator const it2 = format_cache.find(format);
+ if (it2 == format_cache.end())
return 0;
return &(it2->second);
}
converted_file.empty())
return;
LYXERR(Debug::FILES) << BOOST_CURRENT_FUNCTION << ' ' << orig_from
- << ' ' << to_format << ' ' << converted_file
- << std::endl;
+ << ' ' << to_format << ' ' << converted_file
+ << std::endl;
+
+ // FIXME: Should not hardcode this (see bug 3819 for details)
+ if (to_format == "pstex") {
+ FileName const converted_eps(support::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);
+ }
// Is the file in the cache already?
CacheItem * item = pimpl_->find(orig_from, to_format);
Mover const & mover = getMover(to_format);
if (item) {
LYXERR(Debug::FILES) << "ConverterCache::add(" << orig_from << "):\n"
- "The file is already in the cache."
- << std::endl;
+ "The file is already in the cache."
+ << std::endl;
// First test for timestamp
if (timestamp == item->timestamp) {
LYXERR(Debug::FILES) << "Same timestamp."
- << std::endl;
+ << std::endl;
return;
} else {
// Maybe the contents is still the same?
unsigned long const checksum = support::sum(orig_from);
if (checksum == item->checksum) {
LYXERR(Debug::FILES) << "Same checksum."
- << std::endl;
+ << std::endl;
return;
}
item->checksum = checksum;
}
- if (!mover.copy(converted_file, item->cache_name, 0600))
+ 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."
- << std::endl;
+ << orig_from << "):\n"
+ "Could not copy file."
+ << std::endl;
} else {
- CacheItem new_item = CacheItem(orig_from, to_format, timestamp,
+ CacheItem new_item(orig_from, to_format, timestamp,
support::sum(orig_from));
- if (mover.copy(converted_file, new_item.cache_name, 0600))
- pimpl_->cache[orig_from][to_format] = new_item;
- else
+ if (mover.copy(converted_file, new_item.cache_name,
+ support::onlyFilename(new_item.cache_name.absFilename()), 0600)) {
+ FormatCache & format_cache = pimpl_->cache[orig_from];
+ if (format_cache.from_format.empty())
+ format_cache.from_format =
+ formats.getFormatFromFile(orig_from);
+ format_cache.cache[to_format] = new_item;
+ } else
LYXERR(Debug::FILES) << "ConverterCache::add("
- << orig_from << "):\n"
- "Could not copy file."
- << std::endl;
+ << orig_from << "):\n"
+ "Could not copy file."
+ << std::endl;
}
}
if (!lyxrc.use_converter_cache || orig_from.empty())
return;
LYXERR(Debug::FILES) << BOOST_CURRENT_FUNCTION << ' ' << orig_from
- << ' ' << to_format << std::endl;
+ << ' ' << to_format << std::endl;
CacheType::iterator const it1 = pimpl_->cache.find(orig_from);
if (it1 == pimpl_->cache.end())
return;
- FormatCacheType::iterator const it2 = it1->second.find(to_format);
- if (it2 == it1->second.end())
+ FormatCacheType & format_cache = it1->second.cache;
+ FormatCacheType::iterator const it2 = format_cache.find(to_format);
+ if (it2 == format_cache.end())
return;
- it1->second.erase(it2);
- if (it1->second.empty())
+ format_cache.erase(it2);
+ if (format_cache.empty())
pimpl_->cache.erase(it1);
}
+void ConverterCache::remove_all(string const & from_format,
+ string const & to_format) const
+{
+ if (!lyxrc.use_converter_cache)
+ return;
+ CacheType::iterator it1 = pimpl_->cache.begin();
+ while (it1 != pimpl_->cache.end()) {
+ if (it1->second.from_format != from_format) {
+ ++it1;
+ continue;
+ }
+ FormatCacheType & format_cache = it1->second.cache;
+ FormatCacheType::iterator it2 = format_cache.begin();
+ while (it2 != format_cache.end()) {
+ if (it2->first == to_format) {
+ LYXERR(Debug::FILES)
+ << "Removing file cache item "
+ << it1->first
+ << ' ' << to_format << std::endl;
+ support::unlink(it2->second.cache_name);
+ format_cache.erase(it2);
+ // Have to start over again since items in a
+ // map are not ordered
+ it2 = format_cache.begin();
+ } else
+ ++it2;
+ }
+ if (format_cache.empty()) {
+ pimpl_->cache.erase(it1);
+ // Have to start over again since items in a map are
+ // not ordered
+ it1 = pimpl_->cache.begin();
+ } else
+ ++it1;
+ }
+ pimpl_->writeIndex();
+}
+
+
bool ConverterCache::inCache(FileName const & orig_from,
string const & to_format) const
{
if (!lyxrc.use_converter_cache || orig_from.empty())
return false;
LYXERR(Debug::FILES) << BOOST_CURRENT_FUNCTION << ' ' << orig_from
- << ' ' << to_format << std::endl;
+ << ' ' << to_format << std::endl;
CacheItem * const item = pimpl_->find(orig_from, to_format);
if (!item) {
string const & to_format) const
{
LYXERR(Debug::FILES) << BOOST_CURRENT_FUNCTION << ' ' << orig_from
- << ' ' << to_format << std::endl;
+ << ' ' << to_format << std::endl;
CacheItem * const item = pimpl_->find(orig_from, to_format);
BOOST_ASSERT(item);
if (!lyxrc.use_converter_cache || orig_from.empty() || dest.empty())
return false;
LYXERR(Debug::FILES) << BOOST_CURRENT_FUNCTION << ' ' << orig_from
- << ' ' << to_format << ' ' << dest << std::endl;
+ << ' ' << to_format << ' ' << dest << std::endl;
+
+ // FIXME: Should not hardcode this (see bug 3819 for details)
+ if (to_format == "pstex") {
+ FileName const dest_eps(support::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))
+ return false;
+ }
CacheItem * const item = pimpl_->find(orig_from, to_format);
BOOST_ASSERT(item);
Mover const & mover = getMover(to_format);
- return mover.copy(item->cache_name, dest);
+ return mover.copy(item->cache_name, dest,
+ support::onlyFilename(dest.absFilename()));
}
} // namespace lyx