[evince/wip/chpe/load-fd: 29/31] libview: Add EvJobLoad class to load from file descriptor
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evince/wip/chpe/load-fd: 29/31] libview: Add EvJobLoad class to load from file descriptor
- Date: Wed, 1 Dec 2021 20:26:20 +0000 (UTC)
commit ff6994ac3a931910a215eee81e8ab3f311878fbb
Author: Christian Persch <chpe src gnome org>
Date: Wed Dec 1 21:25:02 2021 +0100
libview: Add EvJobLoad class to load from file descriptor
help/reference/libview/libevview-sections.txt | 10 +
libview/ev-jobs.c | 305 +++++++++++++++++++++++++-
libview/ev-jobs.h | 58 +++++
3 files changed, 371 insertions(+), 2 deletions(-)
---
diff --git a/help/reference/libview/libevview-sections.txt b/help/reference/libview/libevview-sections.txt
index 2f8f6e6ef..5b0bb6451 100644
--- a/help/reference/libview/libevview-sections.txt
+++ b/help/reference/libview/libevview-sections.txt
@@ -131,6 +131,8 @@ EvJobLoadStream
EvJobLoadStreamClass
EvJobLoadGFile
EvJobLoadGFileClass
+EvJobLoadFd
+EvJobLoadFdClass
EvJobSave
EvJobSaveClass
EvJobFind
@@ -173,12 +175,20 @@ ev_job_load_set_uri
ev_job_load_set_password
ev_job_load_stream_new
ev_job_load_stream_set_stream
+ev_job_load_stream_set_mime_type
ev_job_load_stream_set_load_flags
ev_job_load_stream_set_password
ev_job_load_gfile_new
ev_job_load_gfile_set_gfile
ev_job_load_gfile_set_load_flags
ev_job_load_gfile_set_password
+ev_job_load_fd_new
+ev_job_load_fd_new_take
+ev_job_load_fd_set_fd
+ev_job_load_fd_take_fd
+ev_job_load_fd_set_set_mime_type
+ev_job_load_fd_set_load_flags
+ev_job_load_fd_set_password
ev_job_save_new
ev_job_find_new
ev_job_find_get_n_results
diff --git a/libview/ev-jobs.c b/libview/ev-jobs.c
index e52e49c81..5b23d1d23 100644
--- a/libview/ev-jobs.c
+++ b/libview/ev-jobs.c
@@ -43,6 +43,13 @@
#include <glib/gstdio.h>
#include <glib/gi18n-lib.h>
#include <unistd.h>
+#include <fcntl.h>
+
+typedef struct _EvJobLoadStreamPrivate EvJobLoadStreamPrivate;
+struct _EvJobLoadStreamPrivate
+{
+ char *mime_type;
+};
static void ev_job_init (EvJob *job);
static void ev_job_class_init (EvJobClass *class);
@@ -100,8 +107,9 @@ G_DEFINE_TYPE (EvJobPageData, ev_job_page_data, EV_TYPE_JOB)
G_DEFINE_TYPE (EvJobThumbnail, ev_job_thumbnail, EV_TYPE_JOB)
G_DEFINE_TYPE (EvJobFonts, ev_job_fonts, EV_TYPE_JOB)
G_DEFINE_TYPE (EvJobLoad, ev_job_load, EV_TYPE_JOB)
-G_DEFINE_TYPE (EvJobLoadStream, ev_job_load_stream, EV_TYPE_JOB)
+G_DEFINE_TYPE_WITH_PRIVATE (EvJobLoadStream, ev_job_load_stream, EV_TYPE_JOB)
G_DEFINE_TYPE (EvJobLoadGFile, ev_job_load_gfile, EV_TYPE_JOB)
+G_DEFINE_TYPE (EvJobLoadFd, ev_job_load_fd, EV_TYPE_JOB)
G_DEFINE_TYPE (EvJobSave, ev_job_save, EV_TYPE_JOB)
G_DEFINE_TYPE (EvJobFind, ev_job_find, EV_TYPE_JOB)
G_DEFINE_TYPE (EvJobLayers, ev_job_layers, EV_TYPE_JOB)
@@ -1198,12 +1206,15 @@ static void
ev_job_load_stream_dispose (GObject *object)
{
EvJobLoadStream *job = EV_JOB_LOAD_STREAM (object);
+ EvJobLoadStreamPrivate *priv = ev_job_load_stream_get_instance_private (job);
if (job->stream) {
g_object_unref (job->stream);
job->stream = NULL;
}
+ g_free (priv->mime_type);
+ priv->mime_type = NULL;
g_free (job->password);
job->password = NULL;
@@ -1214,6 +1225,7 @@ static gboolean
ev_job_load_stream_run (EvJob *job)
{
EvJobLoadStream *job_load_stream = EV_JOB_LOAD_STREAM (job);
+ EvJobLoadStreamPrivate *priv = ev_job_load_stream_get_instance_private (job_load_stream);
GError *error = NULL;
ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
@@ -1242,7 +1254,7 @@ ev_job_load_stream_run (EvJob *job)
&error);
} else {
job->document = ev_document_factory_get_document_for_stream (job_load_stream->stream,
- NULL /* mime-type FIXME? */,
+ priv->mime_type,
job_load_stream->flags,
job->cancellable,
&error);
@@ -1296,6 +1308,19 @@ ev_job_load_stream_set_stream (EvJobLoadStream *job,
job->stream = stream;
}
+void
+ev_job_load_stream_set_mime_type (EvJobLoadStream *job,
+ const char *mime_type)
+{
+ EvJobLoadStreamPrivate *priv;
+
+ g_return_if_fail (EV_IS_JOB_LOAD_STREAM (job));
+
+ priv = ev_job_load_stream_get_instance_private (job);
+ g_free (priv->mime_type);
+ priv->mime_type = g_strdup (mime_type);
+}
+
void
ev_job_load_stream_set_load_flags (EvJobLoadStream *job,
EvDocumentLoadFlags flags)
@@ -1462,6 +1487,282 @@ ev_job_load_gfile_set_password (EvJobLoadGFile *job,
g_free (old_password);
}
+/* EvJobLoadFd */
+
+/**
+ * EvJobLoadFd:
+ *
+ * A job class to load a #EvDocument from a file descriptor
+ * referring to a regular file.
+ *
+ * Since: 3.30
+ */
+
+static int
+ev_dupfd (int fd,
+ GError **error)
+{
+ int new_fd;
+
+ new_fd = fcntl (fd, F_DUPFD_CLOEXEC, 3);
+ if (new_fd == -1) {
+ int errsv = errno;
+ g_set_error_literal (error, G_FILE_ERROR, g_file_error_from_errno (errsv),
+ g_strerror (errsv));
+ }
+
+ return new_fd;
+}
+
+static void
+ev_job_load_fd_init (EvJobLoadFd *job)
+{
+ job->flags = EV_DOCUMENT_LOAD_FLAG_NONE;
+ job->fd = -1;
+
+ EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
+}
+
+static void
+ev_job_load_fd_dispose (GObject *object)
+{
+ EvJobLoadFd *job = EV_JOB_LOAD_FD (object);
+
+ if (job->fd != -1) {
+ close (job->fd);
+ job->fd = -1;
+ }
+
+ g_free (job->mime_type);
+ job->mime_type = NULL;
+ g_free (job->password);
+ job->password = NULL;
+
+ G_OBJECT_CLASS (ev_job_load_fd_parent_class)->dispose (object);
+}
+
+static gboolean
+ev_job_load_fd_run (EvJob *job)
+{
+ EvJobLoadFd *job_load_fd = EV_JOB_LOAD_FD (job);
+ GError *error = NULL;
+ int fd;
+
+ if (job_load_fd->fd == -1) {
+ g_set_error_literal (&error, G_FILE_ERROR, G_FILE_ERROR_BADF,
+ "Invalid file descriptor");
+ goto out;
+ }
+
+ /* We need to dup the FD here since we may need to pass it again
+ * to ev_document_load_fd() if the document is encrypted,
+ * and the previous call to it consumes the FD.
+ */
+ fd = ev_dupfd (job_load_fd->fd, &error);
+ if (fd == -1)
+ goto out;
+
+ ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+
+ ev_document_fc_mutex_lock ();
+
+ /* This job may already have a document even if the job didn't complete
+ because, e.g., a password is required - if so, just reload_fd rather than
+ creating a new instance */
+
+ if (job->document) {
+
+ if (job_load_fd->password) {
+ ev_document_security_set_password (EV_DOCUMENT_SECURITY (job->document),
+ job_load_fd->password);
+ }
+
+ job->failed = FALSE;
+ job->finished = FALSE;
+ g_clear_error (&job->error);
+
+ ev_document_load_fd (job->document,
+ fd,
+ job_load_fd->flags,
+ job->cancellable,
+ &error);
+ fd = -1; /* consumed */
+ } else {
+ job->document = ev_document_factory_get_document_for_fd (fd,
+ job_load_fd->mime_type,
+ job_load_fd->flags,
+ job->cancellable,
+ &error);
+ fd = -1; /* consumed */
+ }
+
+ ev_document_fc_mutex_unlock ();
+
+ out:
+ if (error) {
+ ev_job_failed_from_error (job, error);
+ g_error_free (error);
+ } else {
+ ev_job_succeeded (job);
+ }
+
+ return FALSE;
+}
+
+static void
+ev_job_load_fd_class_init (EvJobLoadFdClass *class)
+{
+ GObjectClass *oclass = G_OBJECT_CLASS (class);
+ EvJobClass *job_class = EV_JOB_CLASS (class);
+
+ oclass->dispose = ev_job_load_fd_dispose;
+ job_class->run = ev_job_load_fd_run;
+}
+
+/**
+ * ev_job_load_fd_new:
+ * @fd: (transfer none):
+ * @mime_type:
+ * @flags:
+ * @error: (nullable): a location to store a #GError, or %NULL
+ *
+ * Creates a new #EvJobLoadFd for @fd. If duplicating @fd fails,
+ * returns %NULL with @error filled in.
+ *
+ * Returns: (tranfer full): the new #EvJobLoadFd, or %NULL
+ *
+ * Since: 3.30
+ */
+EvJob *
+ev_job_load_fd_new (int fd,
+ const char *mime_type,
+ EvDocumentLoadFlags flags,
+ GError **error)
+{
+ EvJobLoadFd *job;
+
+ job = g_object_new (EV_TYPE_JOB_LOAD_FD, NULL);
+ if (!ev_job_load_fd_set_fd (job, fd, error)) {
+ g_object_unref (job);
+ return NULL;
+ }
+
+ ev_job_load_fd_set_mime_type (job, mime_type);
+ ev_job_load_fd_set_load_flags (job, flags);
+
+ return EV_JOB (job);
+}
+
+/**
+ * ev_job_load_new_take:
+ * @fd: (transfer full):
+ * @mime_type:
+ * @flags:
+ *
+ * Creates a new #EvJobLoadFd for @fd.
+ * Note that the job takes ownership of @fd; you must not do anything
+ * with it afterwards.
+ *
+ * Returns: (tranfer full): the new #EvJobLoadFd
+ *
+ * Since: 3.30
+ */
+EvJob *
+ev_job_load_fd_new_take (int fd,
+ const char *mime_type,
+ EvDocumentLoadFlags flags)
+{
+ EvJobLoadFd *job;
+
+ job = g_object_new (EV_TYPE_JOB_LOAD_FD, NULL);
+ ev_job_load_fd_take_fd (job, fd);
+ ev_job_load_fd_set_mime_type (job, mime_type);
+ ev_job_load_fd_set_load_flags (job, flags);
+
+ return EV_JOB (job);
+}
+
+/**
+ * ev_job_load_fd_set_fd:
+ * @job:
+ * @fd: (transfer none):
+ * @error: (nullable): a location to store a #GError, or %NULL
+ *
+ * Sets @fd as the file descriptor in @job. If duplicating @fd fails,
+ * returns %FALSE with @error filled in.
+ *
+ * Returns: %TRUE if the file descriptor could be set
+ *
+ * Since: 3.30
+ */
+gboolean
+ev_job_load_fd_set_fd (EvJobLoadFd *job,
+ int fd,
+ GError **error)
+{
+ g_return_val_if_fail (EV_IS_JOB_LOAD_FD (job), FALSE);
+ g_return_val_if_fail (fd != -1, FALSE);
+
+ job->fd = ev_dupfd (fd, error);
+ return job->fd != -1;
+}
+
+/**
+ * ev_job_load_fd_set_fd:
+ * @job:
+ * @fd: (transfer full):
+ *
+ * Sets @fd as the file descriptor in @job.
+ * Note that @job takes ownership of @fd; you must not do anything
+ * with it afterwards.
+ *
+ * Since: 3.30
+ */
+void
+ev_job_load_fd_take_fd (EvJobLoadFd *job,
+ int fd)
+{
+ g_return_if_fail (EV_IS_JOB_LOAD_FD (job));
+ g_return_if_fail (fd != -1);
+
+ job->fd = fd;
+}
+
+void
+ev_job_load_fd_set_mime_type (EvJobLoadFd *job,
+ const char *mime_type)
+{
+ g_return_if_fail (EV_IS_JOB_LOAD_FD (job));
+ g_return_if_fail (mime_type != NULL);
+
+ g_free (job->mime_type);
+ job->mime_type = g_strdup (mime_type);
+}
+
+void
+ev_job_load_fd_set_load_flags (EvJobLoadFd *job,
+ EvDocumentLoadFlags flags)
+{
+ g_return_if_fail (EV_IS_JOB_LOAD_FD (job));
+
+ job->flags = flags;
+}
+
+void
+ev_job_load_fd_set_password (EvJobLoadFd *job,
+ const char *password)
+{
+ char *old_password;
+
+ ev_debug_message (DEBUG_JOBS, NULL);
+
+ g_return_if_fail (EV_IS_JOB_LOAD_FD (job));
+
+ old_password = job->password;
+ job->password = g_strdup (password);
+ g_free (old_password);
+}
+
/* EvJobSave */
static void
ev_job_save_init (EvJobSave *job)
diff --git a/libview/ev-jobs.h b/libview/ev-jobs.h
index dda9778d3..04bfda0e7 100644
--- a/libview/ev-jobs.h
+++ b/libview/ev-jobs.h
@@ -66,6 +66,9 @@ typedef struct _EvJobLoadStreamClass EvJobLoadStreamClass;
typedef struct _EvJobLoadGFile EvJobLoadGFile;
typedef struct _EvJobLoadGFileClass EvJobLoadGFileClass;
+typedef struct _EvJobLoadFd EvJobLoadFd;
+typedef struct _EvJobLoadFdClass EvJobLoadFdClass;
+
typedef struct _EvJobSave EvJobSave;
typedef struct _EvJobSaveClass EvJobSaveClass;
@@ -159,6 +162,13 @@ typedef struct _EvJobPrintClass EvJobPrintClass;
#define EV_IS_JOB_LOAD_GFILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EV_TYPE_JOB_LOAD_GFILE))
#define EV_JOB_LOAD_GFILE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EV_TYPE_JOB_LOAD_GFILE,
EvJobLoadGFileClass))
+#define EV_TYPE_JOB_LOAD_FD (ev_job_load_fd_get_type())
+#define EV_JOB_LOAD_FD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EV_TYPE_JOB_LOAD_FD, EvJobLoadFd))
+#define EV_IS_JOB_LOAD_FD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EV_TYPE_JOB_LOAD_FD))
+#define EV_JOB_LOAD_FD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EV_TYPE_JOB_LOAD_FD,
EvJobLoadFdClass))
+#define EV_IS_JOB_LOAD_FD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EV_TYPE_JOB_LOAD_FD))
+#define EV_JOB_LOAD_FD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EV_TYPE_JOB_LOAD_FD,
EvJobLoadFdClass))
+
#define EV_TYPE_JOB_SAVE (ev_job_save_get_type())
#define EV_JOB_SAVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EV_TYPE_JOB_SAVE, EvJobSave))
#define EV_IS_JOB_SAVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EV_TYPE_JOB_SAVE))
@@ -416,6 +426,21 @@ struct _EvJobLoadGFileClass
EvJobClass parent_class;
};
+struct _EvJobLoadFd
+{
+ EvJob parent;
+
+ char *mime_type;
+ char *password;
+ int fd;
+ EvDocumentLoadFlags flags;
+};
+
+struct _EvJobLoadFdClass
+{
+ EvJobClass parent_class;
+};
+
struct _EvJobSave
{
EvJob parent;
@@ -610,6 +635,9 @@ EV_PUBLIC
void ev_job_load_stream_set_stream (EvJobLoadStream *job,
GInputStream *stream);
EV_PUBLIC
+void ev_job_load_stream_set_mime_type (EvJobLoadStream *job,
+ const char *mime_type);
+EV_PUBLIC
void ev_job_load_stream_set_load_flags (EvJobLoadStream *job,
EvDocumentLoadFlags flags);
EV_PUBLIC
@@ -632,6 +660,36 @@ EV_PUBLIC
void ev_job_load_gfile_set_password (EvJobLoadGFile *job,
const gchar *password);
+
+/* EvJobLoadFd */
+EV_PUBLIC
+GType ev_job_load_fd_get_type (void) G_GNUC_CONST;
+EV_PUBLIC
+EvJob *ev_job_load_fd_new (int fd,
+ const char *mime_type,
+ EvDocumentLoadFlags flags,
+ GError **error);
+EV_PUBLIC
+EvJob *ev_job_load_fd_new_take (int fd,
+ const char *mime_type,
+ EvDocumentLoadFlags flags);
+EV_PUBLIC
+gboolean ev_job_load_fd_set_fd (EvJobLoadFd *job,
+ int fd,
+ GError **error);
+EV_PUBLIC
+void ev_job_load_fd_take_fd (EvJobLoadFd *job,
+ int fd);
+EV_PUBLIC
+void ev_job_load_fd_set_mime_type (EvJobLoadFd *job,
+ const char *mime_type);
+EV_PUBLIC
+void ev_job_load_fd_set_load_flags (EvJobLoadFd *job,
+ EvDocumentLoadFlags flags);
+EV_PUBLIC
+void ev_job_load_fd_set_password (EvJobLoadFd *job,
+ const gchar *password);
+
/* EvJobSave */
EV_PUBLIC
GType ev_job_save_get_type (void) G_GNUC_CONST;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]