commit 4c6a341ab592b2389083579dba08d1961a0380b7
Author: Jean-Marc Lasgouttes <[email protected]>
Date: Tue Jul 3 11:36:12 2018 +0200
Encapsulate libmagic support in a class
This makes the code much easier to read and, additionally, allows to
parse the magic file with magic_load() only once per session.
As a result, getFormatFromFile is slightly faster.
---
src/Format.cpp | 76 +++++++++++++++++----------------------------
src/support/Magic.h | 77 +++++++++++++++++++++++++++++++++++++++++++++++
src/support/Makefile.am | 1 +
3 files changed, 107 insertions(+), 47 deletions(-)
diff --git a/src/Format.cpp b/src/Format.cpp
index 3b3a10d..feefd1e 100644
--- a/src/Format.cpp
+++ b/src/Format.cpp
@@ -19,11 +19,12 @@
#include "frontends/alert.h" //to be removed?
#include "support/debug.h"
+#include "support/docstream.h"
#include "support/filetools.h"
#include "support/gettext.h"
#include "support/lstrings.h"
+#include "support/Magic.h"
#include "support/mutex.h"
-#include "support/docstream.h"
#include "support/os.h"
#include "support/PathChanger.h"
#include "support/Systemcall.h"
@@ -39,10 +40,6 @@
#include "support/linkback/LinkBackProxy.h"
#endif
-#ifdef HAVE_MAGIC_H
-#include <magic.h>
-#endif
-
using namespace std;
using namespace lyx::support;
@@ -407,52 +404,37 @@ string Formats::getFormatFromFile(FileName const &
filename) const
string psformat;
string format;
-#ifdef HAVE_MAGIC_H
if (filename.exists()) {
- magic_t magic_cookie = magic_open(MAGIC_MIME);
- if (magic_cookie) {
- if (magic_load(magic_cookie, NULL) != 0) {
- LYXERR(Debug::GRAPHICS,
"Formats::getFormatFromFile\n"
- << "\tCouldn't load magic database - "
- << magic_error(magic_cookie));
- } else {
- char const * result = magic_file(magic_cookie,
-
filename.toFilesystemEncoding().c_str());
- string mime;
- if (result)
- mime = token(result, ';', 0);
- else {
- LYXERR(Debug::GRAPHICS,
"Formats::getFormatFromFile\n"
- << "\tCouldn't query magic
database - "
- << magic_error(magic_cookie));
- }
- // our own detection is better for binary files
(can be anything)
- // and different plain text formats
- if (!mime.empty() && mime !=
"application/octet-stream" &&
- mime != "text/plain") {
- Formats::const_iterator cit =
- find_if(formatlist_.begin(),
formatlist_.end(),
- FormatMimeEqual(mime));
- if (cit != formatlist_.end()) {
- LYXERR(Debug::GRAPHICS, "\tgot
format from MIME type: "
- << mime << " -> " <<
cit->name());
- // See special eps/ps handling
below
- if (mime ==
"application/postscript")
- psformat = cit->name();
- else
- format = cit->name();
- }
- }
+ // one instance of Magic that will be reused for next calls
+ // This avoids to read the magic file everytime
+ // If libmagic is not available, Magic::file returns an empty
string.
+ static Magic magic;
+ string const result =
magic.file(filename.toFilesystemEncoding());
+ string const mime = token(result, ';', 0);
+ // our own detection is better for binary files (can be
anything)
+ // and different plain text formats
+ if (!mime.empty() && mime != "application/octet-stream" &&
+ mime != "text/plain") {
+ Formats::const_iterator cit =
+ find_if(formatlist_.begin(), formatlist_.end(),
+ FormatMimeEqual(mime));
+ if (cit != formatlist_.end()) {
+ LYXERR(Debug::GRAPHICS, "\tgot format from MIME
type: "
+ << mime << " -> " << cit->name());
+ // See special eps/ps handling below
+ if (mime == "application/postscript")
+ psformat = cit->name();
+ else
+ format = cit->name();
}
- magic_close(magic_cookie);
- // libmagic recognizes as latex also some formats of
ours
- // such as pstex and pdftex. Therefore we have to
perform
- // additional checks in this case (bug 9244).
- if (!format.empty() && format != "latex")
- return format;
}
+
+ // libmagic recognizes as latex also some formats of ours
+ // such as pstex and pdftex. Therefore we have to perform
+ // additional checks in this case (bug 9244).
+ if (!format.empty() && format != "latex")
+ return format;
}
-#endif
string const ext = getExtension(filename.absFileName());
if (format.empty()) {
diff --git a/src/support/Magic.h b/src/support/Magic.h
new file mode 100644
index 0000000..ca87f0c
--- /dev/null
+++ b/src/support/Magic.h
@@ -0,0 +1,77 @@
+// -*- C++ -*-
+/**
+ * \file Magic.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Jean-Marc Lasgouttes
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef LYX_MAGIC_H
+#define LYX_MAGIC_H
+
+namespace lyx {
+
+#ifdef HAVE_MAGIC_H
+
+#include "support/debug.h"
+
+#include <magic.h>
+
+class Magic {
+public:
+ Magic() : ok_(false) {
+ cookie_ = magic_open(MAGIC_MIME);
+ if (cookie_) {
+ if (magic_load(cookie_, NULL) != 0)
+ LYXERR(Debug::GRAPHICS, "Magic: couldn't load
magic database - "
+ << magic_error(cookie_));
+ else
+ ok_ = true;
+ }
+ }
+
+ ~Magic() {
+ if(cookie_)
+ magic_close(cookie_);
+ }
+
+ // returns a string of the form "mime-type;encoding", or an empty
string on error.
+ std::string file(std::string const & name) const {
+ if (!ok_)
+ return std::string();
+
+ char const * result = magic_file(cookie_, name.c_str());
+ if (result)
+ return result;
+ else
+ LYXERR(Debug::GRAPHICS, "Magic: couldn't query magic
database - "
+ << magic_error(cookie_));
+
+ return std::string();
+ }
+
+private:
+ magic_t cookie_;
+ bool ok_;
+};
+
+#else // !HAVE_MAGIC_T
+
+// A dummy Magic class that always returns an empty result
+class Magic {
+public:
+ Magic() {
+ LYXERR(Debug::GRAPHICS, "Magic: libmagic support not
configured");
+ }
+
+ std::string file(std::string const & name) const { return empty_string;
}
+};
+
+#endif // HAVE_MAGIC_T
+
+}
+
+#endif // LYX_MAGIC_H
diff --git a/src/support/Makefile.am b/src/support/Makefile.am
index d3c902c..c86cd48 100644
--- a/src/support/Makefile.am
+++ b/src/support/Makefile.am
@@ -76,6 +76,7 @@ liblyxsupport_a_SOURCES = \
lyxlib.h \
lyxtime.cpp \
lyxtime.h \
+ Magic.h \
mutex.h \
mutex.cpp \
Messages.cpp \