1
0
mirror of https://gitlab.gnome.org/GNOME/evince synced 2024-06-30 22:54:23 +00:00

libdocument: Add API to create EvDocument from file descriptor

Add new EvDocumentClass vfunc load_fd to load the document from
a file descriptor.
This commit is contained in:
Christian Persch 2021-12-01 21:25:02 +01:00 committed by Germán Poo-Caamaño
parent 24be012d44
commit 11ba63defa
5 changed files with 173 additions and 7 deletions

View File

@ -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>

View File

@ -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:
* @fd: 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)
{

View File

@ -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);

View File

@ -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

View File

@ -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);