[evince/wip/chpe/load-fd: 2/5] libdocument: Add API to create EvDocument from file descriptor
- From: Germán Poo-Caamaño <gpoo src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evince/wip/chpe/load-fd: 2/5] libdocument: Add API to create EvDocument from file descriptor
- Date: Thu, 6 Jan 2022 13:59:56 +0000 (UTC)
commit 5a08c9845cfc360e620017e28db7527a0c0b7baa
Author: Christian Persch <chpe src gnome org>
Date: Wed Dec 1 21:25:02 2021 +0100
libdocument: Add API to create EvDocument from file descriptor
Add new EvDocumentClass vfunc load_fd to load the document from
a file descriptor.
.../libdocument/libevdocument-sections.txt | 2 +
libdocument/ev-document-factory.c | 64 ++++++++++++++-
libdocument/ev-document-factory.h | 9 ++-
libdocument/ev-document.c | 93 +++++++++++++++++++++-
libdocument/ev-document.h | 12 ++-
5 files changed, 173 insertions(+), 7 deletions(-)
---
diff --git a/help/reference/libdocument/libevdocument-sections.txt
b/help/reference/libdocument/libevdocument-sections.txt
index 01211405b..795c947de 100644
--- a/help/reference/libdocument/libevdocument-sections.txt
+++ b/help/reference/libdocument/libevdocument-sections.txt
@@ -368,6 +368,7 @@ ev_document_get_backend_info
ev_document_load
ev_document_load_stream
ev_document_load_gfile
+ev_document_load_fd
ev_document_save
ev_document_get_n_pages
ev_document_get_page
@@ -775,6 +776,7 @@ ev_document_fonts_get_type
ev_document_factory_get_document
ev_document_factory_get_document_for_gfile
ev_document_factory_get_document_for_stream
+ev_document_factory_get_document_for_fd
ev_document_factory_add_filters
</SECTION>
diff --git a/libdocument/ev-document-factory.c b/libdocument/ev-document-factory.c
index ffe180caf..c0718fd9b 100644
--- a/libdocument/ev-document-factory.c
+++ b/libdocument/ev-document-factory.c
@@ -1,6 +1,6 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
/*
- * Copyright (C) 2005, Red Hat, Inc.
+ * Copyright (C) 2005, Red Hat, Inc.
+ * Copyright © 2018 Christian Persch
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -540,6 +540,66 @@ ev_document_factory_get_document_for_stream (GInputStream *stream,
return document;
}
+/**
+ * ev_document_factory_get_document_for_fd:
+ * @stream: a file descriptor
+ * @mime_type: the mime type
+ * @flags: flags from #EvDocumentLoadFlags
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @error: (allow-none): a #GError location to store an error, or %NULL
+ *
+ * Synchronously creates a #EvDocument for the document from @fd using the backend
+ * for loading documents of type @mime_type; or, if the backend does not support
+ * loading from file descriptors, or an error occurred on opening the document,
+ * returns %NULL and fills in @error.
+ * If the document is encrypted, it is returned but also @error is set to
+ * %EV_DOCUMENT_ERROR_ENCRYPTED.
+ *
+ * If the mime type cannot be inferred from the file descriptor, and @mime_type is %NULL,
+ * an error is returned.
+ *
+ * Note that this function takes ownership of @fd; you must not ever
+ * operate on it again. It will be closed automatically if the document
+ * is destroyed, or if this function returns %NULL.
+ *
+ * Returns: (transfer full): a new #EvDocument, or %NULL
+ *
+ * Since: 42.0
+ */
+EvDocument*
+ev_document_factory_get_document_for_fd (int fd,
+ const char *mime_type,
+ EvDocumentLoadFlags flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EvDocument *document;
+
+ g_return_val_if_fail (fd != -1, NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ if (mime_type == NULL) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "Cannot query mime type from file descriptor");
+ close (fd);
+ return NULL;
+ }
+
+ document = ev_document_factory_new_document_for_mime_type (mime_type, error);
+ if (document == NULL) {
+ close (fd);
+ return NULL;
+ }
+
+ if (!ev_document_load_fd (document, fd, flags, cancellable, error)) {
+ /* fd is now consumed */
+ g_object_unref (document);
+ return NULL;
+ }
+
+ return document;
+}
+
static void
file_filter_add_mime_types (EvBackendInfo *info, GtkFileFilter *filter)
{
diff --git a/libdocument/ev-document-factory.h b/libdocument/ev-document-factory.h
index a071a4179..a771346c5 100644
--- a/libdocument/ev-document-factory.h
+++ b/libdocument/ev-document-factory.h
@@ -1,6 +1,5 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
/*
- * Copyright (C) 2005, Red Hat, Inc.
+ * Copyright (C) 2005, Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -51,6 +50,12 @@ EvDocument* ev_document_factory_get_document_for_stream (GInputStream *stream,
EvDocumentLoadFlags flags,
GCancellable *cancellable,
GError **error);
+EV_PUBLIC
+EvDocument* ev_document_factory_get_document_for_fd (int fd,
+ const char *mime_type,
+ EvDocumentLoadFlags flags,
+ GCancellable *cancellable,
+ GError **error);
EV_PUBLIC
void ev_document_factory_add_filters (GtkWidget *chooser, EvDocument *document);
diff --git a/libdocument/ev-document.c b/libdocument/ev-document.c
index 1be739c9b..cfb843384 100644
--- a/libdocument/ev-document.c
+++ b/libdocument/ev-document.c
@@ -1,7 +1,7 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
/*
* Copyright (C) 2009 Carlos Garcia Campos
* Copyright (C) 2004 Marco Pesenti Gritti
+ * Copyright © 2018 Christian Persch
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,6 +23,9 @@
#include <stdlib.h>
#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
#include "ev-document.h"
#include "ev-document-misc.h"
@@ -563,6 +566,92 @@ ev_document_load_gfile (EvDocument *document,
return TRUE;
}
+/**
+ * ev_document_load_fd:
+ * @document: a #EvDocument
+ * @fd: a file descriptor
+ * @flags: flags from #EvDocumentLoadFlags
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @error: (allow-none): a #GError location to store an error, or %NULL
+ *
+ * Synchronously loads the document from @fd, which must refer to
+ * a regular file.
+ *
+ * Note that this function takes ownership of @fd; you must not ever
+ * operate on it again. It will be closed automatically if the document
+ * is destroyed, or if this function returns %NULL.
+ *
+ * See ev_document_load() for more information.
+ *
+ * Returns: %TRUE if loading succeeded, or %FALSE on error with @error filled in
+ *
+ * Since: 42.0
+ */
+gboolean
+ev_document_load_fd (EvDocument *document,
+ int fd,
+ EvDocumentLoadFlags flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EvDocumentClass *klass;
+ struct stat statbuf;
+ int fd_flags;
+
+ g_return_val_if_fail (EV_IS_DOCUMENT (document), FALSE);
+ g_return_val_if_fail (fd != -1, FALSE);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ klass = EV_DOCUMENT_GET_CLASS (document);
+ if (!klass->load_fd) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "Backend does not support loading from file descriptor");
+ close (fd);
+ return FALSE;
+ }
+
+ if (fstat(fd, &statbuf) == -1 ||
+ (fd_flags = fcntl (fd, F_GETFL, &flags)) == -1) {
+ int errsv = errno;
+ g_set_error_literal(error, G_FILE_ERROR,
+ g_file_error_from_errno(errsv),
+ g_strerror(errsv));
+ close (fd);
+ return FALSE;
+ }
+
+ if (!S_ISREG(statbuf.st_mode)) {
+ g_set_error_literal(error, G_FILE_ERROR, G_FILE_ERROR_BADF,
+ "Not a regular file.");
+ close (fd);
+ return FALSE;
+ }
+
+ switch (fd_flags & O_ACCMODE) {
+ case O_RDONLY:
+ case O_RDWR:
+ break;
+ case O_WRONLY:
+ default:
+ g_set_error_literal(error, G_FILE_ERROR, G_FILE_ERROR_BADF,
+ "Not a readable file descriptor.");
+ close (fd);
+ return FALSE;
+ }
+
+ if (!klass->load_fd (document, fd, flags, cancellable, error))
+ return FALSE;
+
+ document->priv->info = _ev_document_get_info (document);
+ document->priv->n_pages = _ev_document_get_n_pages (document);
+
+ if (!(flags & EV_DOCUMENT_LOAD_FLAG_NO_CACHE))
+ ev_document_setup_cache (document);
+
+ return TRUE;
+}
+
/**
* ev_document_save:
* @document: a #EvDocument
@@ -570,7 +659,7 @@ ev_document_load_gfile (EvDocument *document,
* @error: a #GError location to store an error, or %NULL
*
* Saves @document to @uri.
- *
+ *
* Returns: %TRUE on success, or %FALSE on error with @error filled in
*/
gboolean
diff --git a/libdocument/ev-document.h b/libdocument/ev-document.h
index 6bce0ada8..d19543237 100644
--- a/libdocument/ev-document.h
+++ b/libdocument/ev-document.h
@@ -1,4 +1,3 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
/*
* Copyright (C) 2009 Carlos Garcia Campos
* Copyright (C) 2000-2003 Marco Pesenti Gritti
@@ -130,6 +129,11 @@ struct _EvDocumentClass
GError **error);
cairo_surface_t * (* get_thumbnail_surface) (EvDocument *document,
EvRenderContext *rc);
+ gboolean (* load_fd) (EvDocument *document,
+ int fd,
+ EvDocumentLoadFlags flags,
+ GCancellable *cancellable,
+ GError **error);
};
EV_PUBLIC
@@ -189,6 +193,12 @@ gboolean ev_document_load_gfile (EvDocument *document,
GCancellable *cancellable,
GError **error);
EV_PUBLIC
+gboolean ev_document_load_fd (EvDocument *document,
+ int fd,
+ EvDocumentLoadFlags flags,
+ GCancellable *cancellable,
+ GError **error);
+EV_PUBLIC
gboolean ev_document_save (EvDocument *document,
const char *uri,
GError **error);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]