[poppler] 9 commits - CMakeLists.txt glib/poppler-attachment.cc glib/poppler-attachment.h glib/poppler-document.cc glib/poppler-document.h glib/poppler-media.cc glib/poppler-media.h glib/poppler-page.cc glib/poppler-private.h glib/reference goo/gfile.cc goo/gfile.h poppler/FDPDFDocBuilder.cc poppler/FDPDFDocBuilder.h poppler/FILECacheLoader.cc poppler/FILECacheLoader.h poppler/PDFDocFactory.cc poppler/PSOutputDev.cc poppler/PSOutputDev.h poppler/StdinCachedFile.cc poppler/StdinCachedFile.h poppler/StdinPDFDocBuilder.cc poppler/StdinPDFDocBuilder.h poppler/Stream.h test/gtk-test.cc
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Thu Nov 18 23:15:35 UTC 2021
CMakeLists.txt | 8 -
glib/poppler-attachment.cc | 46 +++++++++
glib/poppler-attachment.h | 2
glib/poppler-document.cc | 177 +++++++++++++++++++++++++++++++++++-
glib/poppler-document.h | 7 +
glib/poppler-media.cc | 47 +++++++++
glib/poppler-media.h | 2
glib/poppler-page.cc | 9 +
glib/poppler-private.h | 1
glib/reference/poppler-docs.sgml | 17 +++
glib/reference/poppler-sections.txt | 5 +
goo/gfile.cc | 7 +
goo/gfile.h | 3
poppler/FDPDFDocBuilder.cc | 56 +++++++++++
poppler/FDPDFDocBuilder.h | 17 ++-
poppler/FILECacheLoader.cc | 19 ++-
poppler/FILECacheLoader.h | 16 ++-
poppler/PDFDocFactory.cc | 4
poppler/PSOutputDev.cc | 43 ++++++++
poppler/PSOutputDev.h | 4
poppler/StdinPDFDocBuilder.cc | 36 -------
poppler/Stream.h | 2
test/gtk-test.cc | 57 +++++++----
23 files changed, 499 insertions(+), 86 deletions(-)
New commits:
commit 5914c1d6e8a8dddbb176f37552a4efb27445b909
Author: Christian Persch <chpe at src.gnome.org>
Date: Sat Nov 13 11:03:48 2021 +0100
glib: Add APIs to save to file descriptor
diff --git a/glib/poppler-attachment.cc b/glib/poppler-attachment.cc
index 3195483b..b44edded 100644
--- a/glib/poppler-attachment.cc
+++ b/glib/poppler-attachment.cc
@@ -227,7 +227,8 @@ static gboolean save_helper(const gchar *buf, gsize count, gpointer data, GError
n = fwrite(buf, 1, count, f);
if (n != count) {
- g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errno), _("Error writing to image file: %s"), g_strerror(errno));
+ int errsv = errno;
+ g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errsv), _("Error writing to image file: %s"), g_strerror(errsv));
return FALSE;
}
@@ -274,6 +275,49 @@ gboolean poppler_attachment_save(PopplerAttachment *attachment, const char *file
return result;
}
+/**
+ * poppler_attachment_save_to_fd:
+ * @attachment: A #PopplerAttachment.
+ * @fd: a valid file descriptor open for writing
+ * @error: (allow-none): return location for error, or %NULL.
+ *
+ * Saves @attachment to a file referred to by @fd. If @error is set, %FALSE
+ * will be returned. Possible errors include those in the #G_FILE_ERROR domain
+ * and whatever the save function generates.
+ * Note that this function takes ownership of @fd; you must not operate on it
+ * again, nor close it.
+ *
+ * Return value: %TRUE, if the file successfully saved
+ *
+ * Since: 21.12.0
+ **/
+gboolean poppler_attachment_save_to_fd(PopplerAttachment *attachment, int fd, GError **error)
+{
+ gboolean result;
+ FILE *f;
+
+ g_return_val_if_fail(POPPLER_IS_ATTACHMENT(attachment), FALSE);
+ g_return_val_if_fail(fd != -1, FALSE);
+ g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
+
+ f = fdopen(fd, "wb");
+ if (f == nullptr) {
+ int errsv = errno;
+ g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errsv), _("Failed to open FD %d for writing: %s"), fd, g_strerror(errsv));
+ return FALSE;
+ }
+
+ result = poppler_attachment_save_to_callback(attachment, save_helper, f, error);
+
+ if (fclose(f) < 0) {
+ int errsv = errno;
+ g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errsv), _("Failed to close FD %d, all data may not have been saved: %s"), fd, g_strerror(errsv));
+ return FALSE;
+ }
+
+ return result;
+}
+
#define BUF_SIZE 1024
/**
diff --git a/glib/poppler-attachment.h b/glib/poppler-attachment.h
index 5505a959..b04b3f7b 100644
--- a/glib/poppler-attachment.h
+++ b/glib/poppler-attachment.h
@@ -112,6 +112,8 @@ gsize poppler_attachment_get_size(PopplerAttachment *attachment);
POPPLER_PUBLIC
gboolean poppler_attachment_save(PopplerAttachment *attachment, const char *filename, GError **error);
POPPLER_PUBLIC
+gboolean poppler_attachment_save_to_fd(PopplerAttachment *attachment, int fd, GError **error);
+POPPLER_PUBLIC
gboolean poppler_attachment_save_to_callback(PopplerAttachment *attachment, PopplerAttachmentSaveFunc save_func, gpointer user_data, GError **error);
G_END_DECLS
diff --git a/glib/poppler-document.cc b/glib/poppler-document.cc
index f37ef79f..fd95a468 100644
--- a/glib/poppler-document.cc
+++ b/glib/poppler-document.cc
@@ -579,6 +579,54 @@ gboolean poppler_document_save_a_copy(PopplerDocument *document, const char *uri
return retval;
}
+/**
+ * poppler_document_save_to_fd:
+ * @document: a #PopplerDocument
+ * @fd: a valid file descriptor open for writing
+ * @include_changes: whether to include user changes (e.g. form fills)
+ * @error: (allow-none): return location for an error, or %NULL
+ *
+ * Saves @document. Any change made in the document such as
+ * form fields filled, annotations added or modified
+ * will be saved if @include_changes is %TRUE, or discarded i
+ * @include_changes is %FALSE.
+ *
+ * Note that this function takes ownership of @fd; you must not operate on it
+ * again, nor close it.
+ *
+ * If @error is set, %FALSE will be returned. Possible errors
+ * include those in the #G_FILE_ERROR domain.
+ *
+ * Return value: %TRUE, if the document was successfully saved
+ *
+ * Since: 21.12.0
+ **/
+gboolean poppler_document_save_to_fd(PopplerDocument *document, int fd, gboolean include_changes, GError **error)
+{
+ FILE *file;
+ OutStream *stream;
+ int rv;
+
+ g_return_val_if_fail(POPPLER_IS_DOCUMENT(document), FALSE);
+ g_return_val_if_fail(fd != -1, FALSE);
+
+ file = fdopen(fd, "wb");
+ if (file == nullptr) {
+ int errsv = errno;
+ g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errsv), "Failed to open FD %d for writing: %s", fd, g_strerror(errsv));
+ return FALSE;
+ }
+
+ stream = new FileOutStream(file, 0);
+ if (include_changes)
+ rv = document->doc->saveAs(stream);
+ else
+ rv = document->doc->saveWithoutChangesAs(stream);
+ delete stream;
+
+ return handle_save_error(rv, error);
+}
+
static void poppler_document_finalize(GObject *object)
{
PopplerDocument *document = POPPLER_DOCUMENT(object);
@@ -3390,6 +3438,8 @@ static void poppler_ps_file_class_init(PopplerPSFileClass *klass)
static void poppler_ps_file_init(PopplerPSFile *ps_file)
{
ps_file->out = nullptr;
+ ps_file->fd = -1;
+ ps_file->filename = nullptr;
ps_file->paper_width = -1;
ps_file->paper_height = -1;
ps_file->duplex = FALSE;
@@ -3402,6 +3452,8 @@ static void poppler_ps_file_finalize(GObject *object)
delete ps_file->out;
g_object_unref(ps_file->document);
g_free(ps_file->filename);
+ if (ps_file->fd != -1)
+ close(ps_file->fd);
G_OBJECT_CLASS(poppler_ps_file_parent_class)->finalize(object);
}
@@ -3415,7 +3467,7 @@ static void poppler_ps_file_finalize(GObject *object)
*
* Create a new postscript file to render to
*
- * Return value: a PopplerPSFile
+ * Return value: (transfer full): a PopplerPSFile
**/
PopplerPSFile *poppler_ps_file_new(PopplerDocument *document, const char *filename, int first_page, int n_pages)
{
@@ -3434,6 +3486,38 @@ PopplerPSFile *poppler_ps_file_new(PopplerDocument *document, const char *filena
return ps_file;
}
+/**
+ * poppler_ps_file_new_fd:
+ * @document: a #PopplerDocument
+ * @fd: a valid file descriptor open for writing
+ * @first_page: the first page to print
+ * @n_pages: the number of pages to print
+ *
+ * Create a new postscript file to render to.
+ * Note that this function takes ownership of @fd; you must not operate on it
+ * again, nor close it.
+ *
+ * Return value: (transfer full): a #PopplerPSFile
+ *
+ * Since: 21.12.0
+ **/
+PopplerPSFile *poppler_ps_file_new_fd(PopplerDocument *document, int fd, int first_page, int n_pages)
+{
+ PopplerPSFile *ps_file;
+
+ g_return_val_if_fail(POPPLER_IS_DOCUMENT(document), nullptr);
+ g_return_val_if_fail(fd != -1, nullptr);
+ g_return_val_if_fail(n_pages > 0, nullptr);
+
+ ps_file = (PopplerPSFile *)g_object_new(POPPLER_TYPE_PS_FILE, nullptr);
+ ps_file->document = (PopplerDocument *)g_object_ref(document);
+ ps_file->fd = fd;
+ ps_file->first_page = first_page + 1;
+ ps_file->last_page = first_page + 1 + n_pages - 1;
+
+ return ps_file;
+}
+
/**
* poppler_ps_file_set_paper_size:
* @ps_file: a PopplerPSFile which was not yet printed to.
diff --git a/glib/poppler-document.h b/glib/poppler-document.h
index 177881df..5a0afd53 100644
--- a/glib/poppler-document.h
+++ b/glib/poppler-document.h
@@ -308,6 +308,8 @@ gboolean poppler_document_save(PopplerDocument *document, const char *uri, GErro
POPPLER_PUBLIC
gboolean poppler_document_save_a_copy(PopplerDocument *document, const char *uri, GError **error);
POPPLER_PUBLIC
+gboolean poppler_document_save_to_fd(PopplerDocument *document, int fd, gboolean include_changes, GError **error);
+POPPLER_PUBLIC
gboolean poppler_document_get_id(PopplerDocument *document, gchar **permanent_id, gchar **update_id);
POPPLER_PUBLIC
int poppler_document_get_n_pages(PopplerDocument *document);
@@ -498,6 +500,8 @@ GType poppler_ps_file_get_type(void) G_GNUC_CONST;
POPPLER_PUBLIC
PopplerPSFile *poppler_ps_file_new(PopplerDocument *document, const char *filename, int first_page, int n_pages);
POPPLER_PUBLIC
+PopplerPSFile *poppler_ps_file_new_fd(PopplerDocument *document, int fd, int first_page, int n_pages);
+POPPLER_PUBLIC
void poppler_ps_file_set_paper_size(PopplerPSFile *ps_file, double width, double height);
POPPLER_PUBLIC
void poppler_ps_file_set_duplex(PopplerPSFile *ps_file, gboolean duplex);
diff --git a/glib/poppler-media.cc b/glib/poppler-media.cc
index 6b827485..3966d6c0 100644
--- a/glib/poppler-media.cc
+++ b/glib/poppler-media.cc
@@ -225,7 +225,8 @@ static gboolean save_helper(const gchar *buf, gsize count, gpointer data, GError
n = fwrite(buf, 1, count, f);
if (n != count) {
- g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errno), "Error writing to media file: %s", g_strerror(errno));
+ int errsv = errno;
+ g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errsv), "Error writing to media file: %s", g_strerror(errsv));
return FALSE;
}
@@ -276,6 +277,50 @@ gboolean poppler_media_save(PopplerMedia *poppler_media, const char *filename, G
return result;
}
+/**
+ * poppler_media_save_to_fd:
+ * @poppler_media: a #PopplerMedia
+ * @fd: a valid file descriptor open for writing
+ * @error: (allow-none): return location for error, or %NULL.
+ *
+ * Saves embedded stream of @poppler_media to a file referred to by @fd.
+ * If @error is set, %FALSE will be returned.
+ * Possible errors include those in the #G_FILE_ERROR domain
+ * and whatever the save function generates.
+ * Note that this function takes ownership of @fd; you must not operate on it
+ * again, nor close it.
+ *
+ * Return value: %TRUE, if the file successfully saved
+ *
+ * Since: 21.12.0
+ */
+gboolean poppler_media_save_to_fd(PopplerMedia *poppler_media, int fd, GError **error)
+{
+ gboolean result;
+ FILE *f;
+
+ g_return_val_if_fail(POPPLER_IS_MEDIA(poppler_media), FALSE);
+ g_return_val_if_fail(poppler_media->stream.isStream(), FALSE);
+
+ f = fdopen(fd, "wb");
+
+ if (f == nullptr) {
+ int errsv = errno;
+ g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errsv), "Failed to open FD %d for writing: %s", fd, g_strerror(errsv));
+ return FALSE;
+ }
+
+ result = poppler_media_save_to_callback(poppler_media, save_helper, f, error);
+
+ if (fclose(f) < 0) {
+ int errsv = errno;
+ g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errsv), "Failed to close FD %d, all data may not have been saved: %s", fd, g_strerror(errsv));
+ return FALSE;
+ }
+
+ return result;
+}
+
#define BUF_SIZE 1024
/**
diff --git a/glib/poppler-media.h b/glib/poppler-media.h
index e4a278c6..3d54c785 100644
--- a/glib/poppler-media.h
+++ b/glib/poppler-media.h
@@ -69,6 +69,8 @@ gfloat poppler_media_get_repeat_count(PopplerMedia *poppler_media);
POPPLER_PUBLIC
gboolean poppler_media_save(PopplerMedia *poppler_media, const char *filename, GError **error);
POPPLER_PUBLIC
+gboolean poppler_media_save_to_fd(PopplerMedia *poppler_media, int fd, GError **error);
+POPPLER_PUBLIC
gboolean poppler_media_save_to_callback(PopplerMedia *poppler_media, PopplerMediaSaveFunc save_func, gpointer user_data, GError **error);
G_END_DECLS
diff --git a/glib/poppler-page.cc b/glib/poppler-page.cc
index 684cc07f..a0efd6fa 100644
--- a/glib/poppler-page.cc
+++ b/glib/poppler-page.cc
@@ -1055,8 +1055,13 @@ void poppler_page_render_to_ps(PopplerPage *page, PopplerPSFile *ps_file)
for (int i = ps_file->first_page; i <= ps_file->last_page; ++i) {
pages.push_back(i);
}
- ps_file->out =
- new PSOutputDev(ps_file->filename, ps_file->document->doc, nullptr, pages, psModePS, (int)ps_file->paper_width, (int)ps_file->paper_height, false, ps_file->duplex, 0, 0, 0, 0, psRasterizeWhenNeeded, false, nullptr, nullptr);
+ if (ps_file->fd != -1) {
+ ps_file->out =
+ new PSOutputDev(ps_file->fd, ps_file->document->doc, nullptr, pages, psModePS, (int)ps_file->paper_width, (int)ps_file->paper_height, false, ps_file->duplex, 0, 0, 0, 0, psRasterizeWhenNeeded, false, nullptr, nullptr);
+ } else {
+ ps_file->out = new PSOutputDev(ps_file->filename, ps_file->document->doc, nullptr, pages, psModePS, (int)ps_file->paper_width, (int)ps_file->paper_height, false, ps_file->duplex, 0, 0, 0, 0, psRasterizeWhenNeeded, false,
+ nullptr, nullptr);
+ }
}
ps_file->document->doc->displayPage(ps_file->out, page->index + 1, 72.0, 72.0, 0, false, true, false);
diff --git a/glib/poppler-private.h b/glib/poppler-private.h
index 02967fbf..6c09d039 100644
--- a/glib/poppler-private.h
+++ b/glib/poppler-private.h
@@ -41,6 +41,7 @@ struct _PopplerPSFile
PopplerDocument *document;
PSOutputDev *out;
+ int fd;
char *filename;
int first_page;
int last_page;
diff --git a/glib/reference/poppler-sections.txt b/glib/reference/poppler-sections.txt
index 9e6e17c3..f77aad35 100644
--- a/glib/reference/poppler-sections.txt
+++ b/glib/reference/poppler-sections.txt
@@ -202,6 +202,7 @@ poppler_document_new_from_stream
poppler_document_reset_form
poppler_document_save
poppler_document_save_a_copy
+poppler_document_save_to_fd
poppler_document_set_author
poppler_document_set_creation_date
poppler_document_set_creation_date_time
@@ -242,6 +243,7 @@ poppler_layers_iter_new
poppler_layers_iter_next
poppler_ps_file_free
poppler_ps_file_new
+poppler_ps_file_new_fd
poppler_ps_file_set_duplex
poppler_ps_file_set_paper_size
@@ -344,6 +346,7 @@ poppler_attachment_get_mtime
poppler_attachment_get_name
poppler_attachment_get_size
poppler_attachment_save
+poppler_attachment_save_to_fd
poppler_attachment_save_to_callback
<SUBSECTION Standard>
@@ -594,6 +597,7 @@ poppler_media_get_repeat_count
poppler_media_get_show_controls
poppler_media_is_embedded
poppler_media_save
+poppler_media_save_to_fd
poppler_media_save_to_callback
<SUBSECTION Standard>
diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index 1ae270ab..6c79513b 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -1143,6 +1143,49 @@ PSOutputDev::PSOutputDev(const char *fileName, PDFDoc *docA, char *psTitleA, con
init(outputToFile, f, fileTypeA, psTitleA, docA, pagesA, modeA, imgLLXA, imgLLYA, imgURXA, imgURYA, manualCtrlA, paperWidthA, paperHeightA, noCropA, duplexA, levelA);
}
+PSOutputDev::PSOutputDev(int fdA, PDFDoc *docA, char *psTitleA, const std::vector<int> &pagesA, PSOutMode modeA, int paperWidthA, int paperHeightA, bool noCropA, bool duplexA, int imgLLXA, int imgLLYA, int imgURXA, int imgURYA,
+ PSForceRasterize forceRasterizeA, bool manualCtrlA, PSOutCustomCodeCbk customCodeCbkA, void *customCodeCbkDataA, PSLevel levelA)
+{
+ FILE *f;
+ PSFileType fileTypeA;
+
+ underlayCbk = nullptr;
+ underlayCbkData = nullptr;
+ overlayCbk = nullptr;
+ overlayCbkData = nullptr;
+ customCodeCbk = customCodeCbkA;
+ customCodeCbkData = customCodeCbkDataA;
+
+ fontIDs = nullptr;
+ t1FontNames = nullptr;
+ font8Info = nullptr;
+ font16Enc = nullptr;
+ imgIDs = nullptr;
+ formIDs = nullptr;
+ paperSizes = nullptr;
+ embFontList = nullptr;
+ customColors = nullptr;
+ haveTextClip = false;
+ t3String = nullptr;
+ forceRasterize = forceRasterizeA;
+ psTitle = nullptr;
+
+ // open file or pipe
+ if (fdA == STDOUT_FILENO) {
+ fileTypeA = psStdout;
+ f = stdout;
+ } else {
+ fileTypeA = psFile;
+ if (!(f = fdopen(fdA, "w"))) {
+ error(errIO, -1, "Couldn't open PostScript file descriptor '{0:d}'", fdA);
+ ok = false;
+ return;
+ }
+ }
+
+ init(outputToFile, f, fileTypeA, psTitleA, docA, pagesA, modeA, imgLLXA, imgLLYA, imgURXA, imgURYA, manualCtrlA, paperWidthA, paperHeightA, noCropA, duplexA, levelA);
+}
+
PSOutputDev::PSOutputDev(PSOutputFunc outputFuncA, void *outputStreamA, char *psTitleA, PDFDoc *docA, const std::vector<int> &pagesA, PSOutMode modeA, int paperWidthA, int paperHeightA, bool noCropA, bool duplexA, int imgLLXA, int imgLLYA,
int imgURXA, int imgURYA, PSForceRasterize forceRasterizeA, bool manualCtrlA, PSOutCustomCodeCbk customCodeCbkA, void *customCodeCbkDataA, PSLevel levelA)
{
diff --git a/poppler/PSOutputDev.h b/poppler/PSOutputDev.h
index 6689a603..79769994 100644
--- a/poppler/PSOutputDev.h
+++ b/poppler/PSOutputDev.h
@@ -124,6 +124,10 @@ public:
int imgURXA = 0, int imgURYA = 0, PSForceRasterize forceRasterizeA = psRasterizeWhenNeeded, bool manualCtrlA = false, PSOutCustomCodeCbk customCodeCbkA = nullptr, void *customCodeCbkDataA = nullptr,
PSLevel levelA = psLevel2);
+ // Open a PSOutputDev that will write to a file descriptor
+ PSOutputDev(int fdA, PDFDoc *docA, char *psTitleA, const std::vector<int> &pages, PSOutMode modeA, int paperWidthA = -1, int paperHeightA = -1, bool noCrop = false, bool duplexA = true, int imgLLXA = 0, int imgLLYA = 0, int imgURXA = 0,
+ int imgURYA = 0, PSForceRasterize forceRasterizeA = psRasterizeWhenNeeded, bool manualCtrlA = false, PSOutCustomCodeCbk customCodeCbkA = nullptr, void *customCodeCbkDataA = nullptr, PSLevel levelA = psLevel2);
+
// Open a PSOutputDev that will write to a generic stream.
// pages has to be sorted in increasing order
PSOutputDev(PSOutputFunc outputFuncA, void *outputStreamA, char *psTitleA, PDFDoc *docA, const std::vector<int> &pages, PSOutMode modeA, int paperWidthA = -1, int paperHeightA = -1, bool noCrop = false, bool duplexA = true,
commit c3f1ece62ac52587308e44d3e170d864372875f2
Author: Christian Persch <chpe at src.gnome.org>
Date: Sat Nov 13 11:03:48 2021 +0100
glib: Add poppler_document_new_from_fd
While it's already possible to create a PopplerDocument
for STDIN by using fd://0 as the URI, it was not yet possible
to create a PopplerDocument from a file descriptor.
This adds poppler_document_new_from_fd(), which accepts
a readable FD for a regular file, or for STDIN.
Add a --fd option to test/gtk-test to test this. When used,
gtk-test arguments are FD numbers instead of filenames or URIs.
To test, use e.g.
$ 3<test.pdf ./gtk-test --fd 3
diff --git a/glib/poppler-document.cc b/glib/poppler-document.cc
index 38d89b71..f37ef79f 100644
--- a/glib/poppler-document.cc
+++ b/glib/poppler-document.cc
@@ -25,11 +25,21 @@
#include "config.h"
#include <cstring>
+#ifndef G_OS_WIN32
+# include <fcntl.h>
+# include <sys/stat.h>
+# include <sys/types.h>
+# include <unistd.h>
+#endif
+
#ifndef __GI_SCANNER__
# include <memory>
+# include <goo/gfile.h>
# include <splash/SplashBitmap.h>
+# include <CachedFile.h>
# include <DateInfo.h>
+# include <FILECacheLoader.h>
# include <GlobalParams.h>
# include <PDFDoc.h>
# include <Outline.h>
@@ -400,6 +410,87 @@ PopplerDocument *poppler_document_new_from_gfile(GFile *file, const char *passwo
return document;
}
+/**
+ * poppler_document_new_from_fd:
+ * @fd: a valid file descriptor
+ * @password: (allow-none): password to unlock the file with, or %NULL
+ * @error: (allow-none): Return location for an error, or %NULL
+ *
+ * Creates a new #PopplerDocument reading the PDF contents from the file
+ * descriptor @fd. @fd must refer to a regular file, or STDIN, and be open
+ * for reading.
+ * Possible errors include those in the #POPPLER_ERROR and #G_FILE_ERROR
+ * domains.
+ * Note that this function takes ownership of @fd; you must not operate on it
+ * again, nor close it.
+ *
+ * Returns: (transfer full): a new #PopplerDocument, or %NULL
+ *
+ * Since: 21.12.0
+ */
+PopplerDocument *poppler_document_new_from_fd(int fd, const char *password, GError **error)
+{
+#ifndef G_OS_WIN32
+ struct stat statbuf;
+ int flags;
+ BaseStream *stream;
+ PDFDoc *newDoc;
+ GooString *password_g;
+
+ g_return_val_if_fail(fd != -1, nullptr);
+
+ auto initer = std::make_unique<GlobalParamsIniter>(_poppler_error_cb);
+
+ if (fstat(fd, &statbuf) == -1 || (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 nullptr;
+ }
+
+ switch (flags & O_ACCMODE) {
+ case O_RDONLY:
+ case O_RDWR:
+ break;
+ case O_WRONLY:
+ default:
+ g_set_error(error, G_FILE_ERROR, G_FILE_ERROR_BADF, "File descriptor %d is not readable", fd);
+ close(fd);
+ return nullptr;
+ }
+
+ if (fd == STDIN_FILENO || !S_ISREG(statbuf.st_mode)) {
+ FILE *file;
+ if (fd == STDIN_FILENO) {
+ file = stdin;
+ } else {
+ file = fdopen(fd, "rb");
+ if (!file) {
+ int errsv = errno;
+ g_set_error_literal(error, G_FILE_ERROR, g_file_error_from_errno(errsv), g_strerror(errsv));
+ fclose(file);
+ return nullptr;
+ }
+ }
+
+ CachedFile *cachedFile = new CachedFile(new FILECacheLoader(file), nullptr);
+ stream = new CachedFileStream(cachedFile, 0, false, cachedFile->getLength(), Object(objNull));
+ } else {
+ GooFile *file = GooFile::open(fd);
+ stream = new FileStream(file, 0, false, file->size(), Object(objNull));
+ }
+
+ password_g = poppler_password_to_latin1(password);
+ newDoc = new PDFDoc(stream, password_g, password_g);
+ delete password_g;
+
+ return _poppler_document_new_from_pdfdoc(std::move(initer), newDoc, error);
+#else
+ g_set_error_literal(error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Not supported on win32");
+ return nullptr;
+#endif /* G_OS_WIN32 */
+}
+
static gboolean handle_save_error(int err_code, GError **error)
{
switch (err_code) {
diff --git a/glib/poppler-document.h b/glib/poppler-document.h
index 34d78d4c..177881df 100644
--- a/glib/poppler-document.h
+++ b/glib/poppler-document.h
@@ -290,6 +290,7 @@ typedef enum
POPPLER_PUBLIC
GType poppler_document_get_type(void) G_GNUC_CONST;
+
POPPLER_PUBLIC
PopplerDocument *poppler_document_new_from_file(const char *uri, const char *password, GError **error);
POPPLER_PUBLIC
@@ -301,6 +302,8 @@ PopplerDocument *poppler_document_new_from_stream(GInputStream *stream, goffset
POPPLER_PUBLIC
PopplerDocument *poppler_document_new_from_gfile(GFile *file, const char *password, GCancellable *cancellable, GError **error);
POPPLER_PUBLIC
+PopplerDocument *poppler_document_new_from_fd(int fd, const char *password, GError **error);
+POPPLER_PUBLIC
gboolean poppler_document_save(PopplerDocument *document, const char *uri, GError **error);
POPPLER_PUBLIC
gboolean poppler_document_save_a_copy(PopplerDocument *document, const char *uri, GError **error);
diff --git a/glib/reference/poppler-sections.txt b/glib/reference/poppler-sections.txt
index 8ad07b09..9e6e17c3 100644
--- a/glib/reference/poppler-sections.txt
+++ b/glib/reference/poppler-sections.txt
@@ -195,6 +195,7 @@ poppler_document_has_javascript
poppler_document_is_linearized
poppler_document_new_from_bytes
poppler_document_new_from_data
+poppler_document_new_from_fd
poppler_document_new_from_file
poppler_document_new_from_gfile
poppler_document_new_from_stream
diff --git a/test/gtk-test.cc b/test/gtk-test.cc
index fcefd8b1..4c09a8d6 100644
--- a/test/gtk-test.cc
+++ b/test/gtk-test.cc
@@ -15,15 +15,18 @@
#include <poppler.h>
#include <poppler-private.h>
#include <gtk/gtk.h>
+#include <cerrno>
#include <cmath>
static int requested_page = 0;
static gboolean cairo_output = FALSE;
static gboolean splash_output = FALSE;
+static gboolean args_are_fds = FALSE;
static const char **file_arguments = nullptr;
static const GOptionEntry options[] = { { "cairo", 'c', 0, G_OPTION_ARG_NONE, &cairo_output, "Cairo Output Device", nullptr },
{ "splash", 's', 0, G_OPTION_ARG_NONE, &splash_output, "Splash Output Device", nullptr },
{ "page", 'p', 0, G_OPTION_ARG_INT, &requested_page, "Page number", "PAGE" },
+ { "fd", 'f', 0, G_OPTION_ARG_NONE, &args_are_fds, "File descriptors", nullptr },
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &file_arguments, nullptr, "PDF-FILES…" },
{} };
@@ -336,30 +339,48 @@ int main(int argc, char *argv[])
for (int i = 0; file_arguments[i]; i++) {
View *view;
GFile *file;
- PopplerDocument *doc;
+ PopplerDocument *doc = nullptr;
GError *error = nullptr;
-
- file = g_file_new_for_commandline_arg(file_arguments[i]);
- doc = poppler_document_new_from_gfile(file, nullptr, nullptr, &error);
- if (!doc) {
- gchar *uri;
-
- uri = g_file_get_uri(file);
- g_printerr("Error opening document %s: %s\n", uri, error->message);
- g_error_free(error);
- g_free(uri);
+ const char *arg;
+
+ arg = file_arguments[i];
+ if (args_are_fds) {
+ char *end;
+ gint64 v;
+
+ errno = 0;
+ end = nullptr;
+ v = g_ascii_strtoll(arg, &end, 10);
+ if (errno || end == arg || v == -1 || v < G_MININT || v > G_MAXINT) {
+ g_set_error(&error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Failed to parse \"%s\" as file descriptor number", arg);
+ } else {
+ doc = poppler_document_new_from_fd(int(v), nullptr, &error);
+ }
+ } else {
+ file = g_file_new_for_commandline_arg(arg);
+ doc = poppler_document_new_from_gfile(file, nullptr, nullptr, &error);
+ if (!doc) {
+ gchar *uri;
+
+ uri = g_file_get_uri(file);
+ g_prefix_error(&error, "%s: ", uri);
+ g_free(uri);
+ }
g_object_unref(file);
-
- continue;
}
- g_object_unref(file);
- view = view_new(doc);
- view_list = g_list_prepend(view_list, view);
- view_set_page(view, CLAMP(requested_page, 0, poppler_document_get_n_pages(doc) - 1));
+ if (doc) {
+ view = view_new(doc);
+ view_list = g_list_prepend(view_list, view);
+ view_set_page(view, CLAMP(requested_page, 0, poppler_document_get_n_pages(doc) - 1));
+ } else {
+ g_printerr("Error opening document: %s\n", error->message);
+ g_error_free(error);
+ }
}
- gtk_main();
+ if (view_list != nullptr)
+ gtk_main();
return 0;
}
commit 8d5d591d1910a60608bdbafd92179e8dec918bff
Author: Christian Persch <chpe at src.gnome.org>
Date: Sat Nov 13 11:03:48 2021 +0100
glib: docs: Add index for new API
diff --git a/glib/reference/poppler-docs.sgml b/glib/reference/poppler-docs.sgml
index 53be6d2d..c1b5e2b5 100644
--- a/glib/reference/poppler-docs.sgml
+++ b/glib/reference/poppler-docs.sgml
@@ -126,6 +126,10 @@
<title>Index of new symbols in 21.05.0</title>
<xi:include href="xml/api-index-21.05.0.xml"><xi:fallback /></xi:include>
</index>
+ <index id="api-index-21-12-0">
+ <title>Index of new symbols in 21.12.0</title>
+ <xi:include href="xml/api-index-21.12.0.xml"><xi:fallback /></xi:include>
+ </index>
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
</book>
commit 7db45fac4947e99c9f1985dfa3c82bd612d64cb0
Author: Christian Persch <chpe at src.gnome.org>
Date: Sat Nov 13 11:03:48 2021 +0100
glib: docs: Add missing API indices for new symbols
diff --git a/glib/reference/poppler-docs.sgml b/glib/reference/poppler-docs.sgml
index 102880ac..53be6d2d 100644
--- a/glib/reference/poppler-docs.sgml
+++ b/glib/reference/poppler-docs.sgml
@@ -114,7 +114,18 @@
<title>Index of new symbols in 0.90</title>
<xi:include href="xml/api-index-0.90.xml"><xi:fallback /></xi:include>
</index>
-
+ <index id="api-index-20-04-0">
+ <title>Index of new symbols in 20.04.0</title>
+ <xi:include href="xml/api-index-20.04.0.xml"><xi:fallback /></xi:include>
+ </index>
+ <index id="api-index-20-09-0">
+ <title>Index of new symbols in 20.09.0</title>
+ <xi:include href="xml/api-index-20.09.0.xml"><xi:fallback /></xi:include>
+ </index>
+ <index id="api-index-21-05-0">
+ <title>Index of new symbols in 21.05.0</title>
+ <xi:include href="xml/api-index-21.05.0.xml"><xi:fallback /></xi:include>
+ </index>
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
</book>
commit ff1b0aa530a1eb5b64119f3129434981bfc12e8e
Author: Christian Persch <chpe at src.gnome.org>
Date: Sat Nov 13 11:03:48 2021 +0100
build: Rename StdinPDFDocBuilder to FileDescriptorPDFDocBuilder
... since it's not for just stdin anymore.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0e0048cf..7e959305 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -407,6 +407,7 @@ set(poppler_SRCS
poppler/Decrypt.cc
poppler/Dict.cc
poppler/Error.cc
+ poppler/FDPDFDocBuilder.cc
poppler/FILECacheLoader.cc
poppler/FileSpec.cc
poppler/FontEncodingTables.cc
@@ -454,7 +455,6 @@ set(poppler_SRCS
poppler/TextOutputDev.cc
poppler/PageLabelInfo.cc
poppler/SecurityHandler.cc
- poppler/StdinPDFDocBuilder.cc
poppler/Sound.cc
poppler/ViewerPreferences.cc
poppler/Movie.cc
@@ -614,6 +614,7 @@ if(ENABLE_UNSTABLE_API_ABI_HEADERS)
poppler/Decrypt.h
poppler/Dict.h
poppler/Error.h
+ poppler/FDPDFDocBuilder.h
poppler/FILECacheLoader.h
poppler/FileSpec.h
poppler/FontEncodingTables.h
@@ -672,7 +673,6 @@ if(ENABLE_UNSTABLE_API_ABI_HEADERS)
poppler/PSOutputDev.h
poppler/TextOutputDev.h
poppler/SecurityHandler.h
- poppler/StdinPDFDocBuilder.h
poppler/BBoxOutputDev.h
poppler/UTF.h
poppler/Sound.h
diff --git a/poppler/StdinPDFDocBuilder.cc b/poppler/FDPDFDocBuilder.cc
similarity index 76%
rename from poppler/StdinPDFDocBuilder.cc
rename to poppler/FDPDFDocBuilder.cc
index ecf42b0f..4be7927b 100644
--- a/poppler/StdinPDFDocBuilder.cc
+++ b/poppler/FDPDFDocBuilder.cc
@@ -1,6 +1,6 @@
//========================================================================
//
-// StdinPDFDocBuilder.cc
+// FileDescriptorPDFDocBuilder.cc
//
// This file is licensed under the GPLv2 or later
//
@@ -14,15 +14,15 @@
#include <cstdio>
-#include "StdinPDFDocBuilder.h"
+#include "FDPDFDocBuilder.h"
#include "FILECacheLoader.h"
#include "CachedFile.h"
//------------------------------------------------------------------------
-// StdinPDFDocBuilder
+// FileDescriptorPDFDocBuilder
//------------------------------------------------------------------------
-int StdinPDFDocBuilder::parseFdFromUri(const GooString &uri)
+int FileDescriptorPDFDocBuilder::parseFdFromUri(const GooString &uri)
{
int fd = -1;
char c;
@@ -32,7 +32,7 @@ int StdinPDFDocBuilder::parseFdFromUri(const GooString &uri)
return fd;
}
-std::unique_ptr<PDFDoc> StdinPDFDocBuilder::buildPDFDoc(const GooString &uri, GooString *ownerPassword, GooString *userPassword, void *guiDataA)
+std::unique_ptr<PDFDoc> FileDescriptorPDFDocBuilder::buildPDFDoc(const GooString &uri, GooString *ownerPassword, GooString *userPassword, void *guiDataA)
{
const auto fd = parseFdFromUri(uri);
if (fd == -1)
@@ -50,7 +50,7 @@ std::unique_ptr<PDFDoc> StdinPDFDocBuilder::buildPDFDoc(const GooString &uri, Go
return std::make_unique<PDFDoc>(new CachedFileStream(cachedFile, 0, false, cachedFile->getLength(), Object(objNull)), ownerPassword, userPassword);
}
-bool StdinPDFDocBuilder::supports(const GooString &uri)
+bool FileDescriptorPDFDocBuilder::supports(const GooString &uri)
{
return parseFdFromUri(uri) != -1;
}
diff --git a/poppler/StdinPDFDocBuilder.h b/poppler/FDPDFDocBuilder.h
similarity index 73%
rename from poppler/StdinPDFDocBuilder.h
rename to poppler/FDPDFDocBuilder.h
index 76c69ef1..f4a19bed 100644
--- a/poppler/StdinPDFDocBuilder.h
+++ b/poppler/FDPDFDocBuilder.h
@@ -1,6 +1,6 @@
//========================================================================
//
-// StdinPDFDocBuilder.h
+// FileDescriptorPDFDocBuilder.h
//
// This file is licensed under the GPLv2 or later
//
@@ -10,18 +10,18 @@
//
//========================================================================
-#ifndef STDINPDFDOCBUILDER_H
-#define STDINPDFDOCBUILDER_H
+#ifndef FDPDFDOCBUILDER_H
+#define FDPDFDOCBUILDER_H
#include "PDFDocBuilder.h"
//------------------------------------------------------------------------
-// StdinPDFDocBuilder
+// FileDescriptorPDFDocBuilder
//
-// The StdinPDFDocBuilder implements a PDFDocBuilder that read from a file descriptor.
+// The FileDescriptorPDFDocBuilder implements a PDFDocBuilder that read from a file descriptor.
//------------------------------------------------------------------------
-class StdinPDFDocBuilder : public PDFDocBuilder
+class FileDescriptorPDFDocBuilder : public PDFDocBuilder
{
public:
@@ -32,4 +32,4 @@ private:
int parseFdFromUri(const GooString &uri);
};
-#endif /* STDINPDFDOCBUILDER_H */
+#endif /* FDPDFDOCBUILDER_H */
diff --git a/poppler/PDFDocFactory.cc b/poppler/PDFDocFactory.cc
index e4797074..a807ab3f 100644
--- a/poppler/PDFDocFactory.cc
+++ b/poppler/PDFDocFactory.cc
@@ -19,7 +19,7 @@
#include "goo/GooString.h"
#include "PDFDoc.h"
#include "LocalPDFDocBuilder.h"
-#include "StdinPDFDocBuilder.h"
+#include "FDPDFDocBuilder.h"
#ifdef ENABLE_LIBCURL
# include "CurlPDFDocBuilder.h"
#endif
@@ -37,7 +37,7 @@ PDFDocFactory::PDFDocFactory(std::vector<PDFDocBuilder *> *pdfDocBuilders)
builders = new std::vector<PDFDocBuilder *>();
}
builders->push_back(new LocalPDFDocBuilder());
- builders->push_back(new StdinPDFDocBuilder());
+ builders->push_back(new FileDescriptorPDFDocBuilder());
#ifdef ENABLE_LIBCURL
builders->push_back(new CurlPDFDocBuilder());
#endif
commit 661debdf700d7a13a8373f681e3729fcbb6aa573
Author: Christian Persch <chpe at src.gnome.org>
Date: Sat Nov 13 11:03:48 2021 +0100
build: Rename StdinCacheLoader to FILECacheLoader
... since it's not for just stdin anymore.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1f2e25ba..0e0048cf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -407,6 +407,7 @@ set(poppler_SRCS
poppler/Decrypt.cc
poppler/Dict.cc
poppler/Error.cc
+ poppler/FILECacheLoader.cc
poppler/FileSpec.cc
poppler/FontEncodingTables.cc
poppler/Form.cc
@@ -453,7 +454,6 @@ set(poppler_SRCS
poppler/TextOutputDev.cc
poppler/PageLabelInfo.cc
poppler/SecurityHandler.cc
- poppler/StdinCachedFile.cc
poppler/StdinPDFDocBuilder.cc
poppler/Sound.cc
poppler/ViewerPreferences.cc
@@ -614,6 +614,7 @@ if(ENABLE_UNSTABLE_API_ABI_HEADERS)
poppler/Decrypt.h
poppler/Dict.h
poppler/Error.h
+ poppler/FILECacheLoader.h
poppler/FileSpec.h
poppler/FontEncodingTables.h
poppler/FontInfo.h
@@ -671,7 +672,6 @@ if(ENABLE_UNSTABLE_API_ABI_HEADERS)
poppler/PSOutputDev.h
poppler/TextOutputDev.h
poppler/SecurityHandler.h
- poppler/StdinCachedFile.h
poppler/StdinPDFDocBuilder.h
poppler/BBoxOutputDev.h
poppler/UTF.h
diff --git a/poppler/StdinCachedFile.cc b/poppler/FILECacheLoader.cc
similarity index 79%
rename from poppler/StdinCachedFile.cc
rename to poppler/FILECacheLoader.cc
index 530bf931..fcacc2f4 100644
--- a/poppler/StdinCachedFile.cc
+++ b/poppler/FILECacheLoader.cc
@@ -1,6 +1,6 @@
//========================================================================
//
-// StdinCachedFile.cc
+// FILECacheLoader.cc
//
// This file is licensed under the GPLv2 or later
//
@@ -13,22 +13,20 @@
#include <config.h>
-#include "StdinCachedFile.h"
+#include "FILECacheLoader.h"
#if defined(_WIN32) || defined(__CYGWIN__)
# include <fcntl.h> // for O_BINARY
# include <io.h> // for _setmode
#endif
-StdinCacheLoader::~StdinCacheLoader()
+FILECacheLoader::~FILECacheLoader()
{
-#ifndef _WIN32
if (file != stdin)
fclose(file);
-#endif
}
-size_t StdinCacheLoader::init(GooString *dummy, CachedFile *cachedFile)
+size_t FILECacheLoader::init(GooString *dummy, CachedFile *cachedFile)
{
size_t read, size = 0;
char buf[CachedFileChunkSize];
@@ -47,7 +45,7 @@ size_t StdinCacheLoader::init(GooString *dummy, CachedFile *cachedFile)
return size;
}
-int StdinCacheLoader::load(const std::vector<ByteRange> &ranges, CachedFileWriter *writer)
+int FILECacheLoader::load(const std::vector<ByteRange> &ranges, CachedFileWriter *writer)
{
return 0;
}
diff --git a/poppler/StdinCachedFile.h b/poppler/FILECacheLoader.h
similarity index 66%
rename from poppler/StdinCachedFile.h
rename to poppler/FILECacheLoader.h
index f95c44fd..5ce0c150 100644
--- a/poppler/StdinCachedFile.h
+++ b/poppler/FILECacheLoader.h
@@ -1,6 +1,6 @@
//========================================================================
//
-// StdinCachedFile.h
+// FILECacheLoader.h
//
// This file is licensed under the GPLv2 or later
//
@@ -9,22 +9,22 @@
//
//========================================================================
-#ifndef STDINCACHELOADER_H
-#define STDINCACHELOADER_H
+#ifndef FILECACHELOADER_H
+#define FILECACHELOADER_H
#include "CachedFile.h"
#include <cstdio>
-class POPPLER_PRIVATE_EXPORT StdinCacheLoader : public CachedFileLoader
+class POPPLER_PRIVATE_EXPORT FILECacheLoader : public CachedFileLoader
{
FILE *file = stdin;
public:
- StdinCacheLoader() = default;
- ~StdinCacheLoader() override;
+ FILECacheLoader() = default;
+ ~FILECacheLoader() override;
- explicit StdinCacheLoader(FILE *fileA) : file(fileA) { }
+ explicit FILECacheLoader(FILE *fileA) : file(fileA) { }
size_t init(GooString *dummy, CachedFile *cachedFile) override;
int load(const std::vector<ByteRange> &ranges, CachedFileWriter *writer) override;
diff --git a/poppler/StdinPDFDocBuilder.cc b/poppler/StdinPDFDocBuilder.cc
index 02aefdbe..ecf42b0f 100644
--- a/poppler/StdinPDFDocBuilder.cc
+++ b/poppler/StdinPDFDocBuilder.cc
@@ -15,8 +15,8 @@
#include <cstdio>
#include "StdinPDFDocBuilder.h"
+#include "FILECacheLoader.h"
#include "CachedFile.h"
-#include "StdinCachedFile.h"
//------------------------------------------------------------------------
// StdinPDFDocBuilder
@@ -46,7 +46,7 @@ std::unique_ptr<PDFDoc> StdinPDFDocBuilder::buildPDFDoc(const GooString &uri, Go
if (!file)
return {};
- CachedFile *cachedFile = new CachedFile(new StdinCacheLoader(file), nullptr);
+ CachedFile *cachedFile = new CachedFile(new FILECacheLoader(file), nullptr);
return std::make_unique<PDFDoc>(new CachedFileStream(cachedFile, 0, false, cachedFile->getLength(), Object(objNull)), ownerPassword, userPassword);
}
commit 19a8e85d7d903fbc826416252b4fbce1644c65f8
Author: Christian Persch <chpe at src.gnome.org>
Date: Sat Nov 13 11:03:48 2021 +0100
poppler: Make StdinCacheLoader more generic
Despite its name, StdinCacheLoader really works with any FILE*, not just
stdin. Add a constructor taking a FILE* to set the file it operates on.
This will be used in glib/ in a subsequent commit.
diff --git a/poppler/StdinCachedFile.cc b/poppler/StdinCachedFile.cc
index a5110be0..530bf931 100644
--- a/poppler/StdinCachedFile.cc
+++ b/poppler/StdinCachedFile.cc
@@ -19,7 +19,14 @@
# include <fcntl.h> // for O_BINARY
# include <io.h> // for _setmode
#endif
-#include <cstdio>
+
+StdinCacheLoader::~StdinCacheLoader()
+{
+#ifndef _WIN32
+ if (file != stdin)
+ fclose(file);
+#endif
+}
size_t StdinCacheLoader::init(GooString *dummy, CachedFile *cachedFile)
{
@@ -27,12 +34,12 @@ size_t StdinCacheLoader::init(GooString *dummy, CachedFile *cachedFile)
char buf[CachedFileChunkSize];
#if defined(_WIN32) || defined(__CYGWIN__)
- _setmode(fileno(stdin), O_BINARY);
+ _setmode(fileno(file), O_BINARY);
#endif
CachedFileWriter writer = CachedFileWriter(cachedFile, nullptr);
do {
- read = fread(buf, 1, CachedFileChunkSize, stdin);
+ read = fread(buf, 1, CachedFileChunkSize, file);
(writer.write)(buf, CachedFileChunkSize);
size += read;
} while (read == CachedFileChunkSize);
diff --git a/poppler/StdinCachedFile.h b/poppler/StdinCachedFile.h
index 7ce6dbc2..f95c44fd 100644
--- a/poppler/StdinCachedFile.h
+++ b/poppler/StdinCachedFile.h
@@ -14,10 +14,18 @@
#include "CachedFile.h"
+#include <cstdio>
+
class POPPLER_PRIVATE_EXPORT StdinCacheLoader : public CachedFileLoader
{
+ FILE *file = stdin;
public:
+ StdinCacheLoader() = default;
+ ~StdinCacheLoader() override;
+
+ explicit StdinCacheLoader(FILE *fileA) : file(fileA) { }
+
size_t init(GooString *dummy, CachedFile *cachedFile) override;
int load(const std::vector<ByteRange> &ranges, CachedFileWriter *writer) override;
};
diff --git a/poppler/StdinPDFDocBuilder.cc b/poppler/StdinPDFDocBuilder.cc
index b84420b2..02aefdbe 100644
--- a/poppler/StdinPDFDocBuilder.cc
+++ b/poppler/StdinPDFDocBuilder.cc
@@ -12,6 +12,8 @@
#include <config.h>
+#include <cstdio>
+
#include "StdinPDFDocBuilder.h"
#include "CachedFile.h"
#include "StdinCachedFile.h"
@@ -20,17 +22,35 @@
// StdinPDFDocBuilder
//------------------------------------------------------------------------
+int StdinPDFDocBuilder::parseFdFromUri(const GooString &uri)
+{
+ int fd = -1;
+ char c;
+ if (sscanf(uri.c_str(), "fd://%d%c", &fd, &c) != 1)
+ return -1;
+
+ return fd;
+}
+
std::unique_ptr<PDFDoc> StdinPDFDocBuilder::buildPDFDoc(const GooString &uri, GooString *ownerPassword, GooString *userPassword, void *guiDataA)
{
- CachedFile *cachedFile = new CachedFile(new StdinCacheLoader(), nullptr);
+ const auto fd = parseFdFromUri(uri);
+ if (fd == -1)
+ return {};
+
+ FILE *file;
+ if (fd == STDIN_FILENO)
+ file = stdin;
+ else
+ file = fdopen(fd, "rb");
+ if (!file)
+ return {};
+
+ CachedFile *cachedFile = new CachedFile(new StdinCacheLoader(file), nullptr);
return std::make_unique<PDFDoc>(new CachedFileStream(cachedFile, 0, false, cachedFile->getLength(), Object(objNull)), ownerPassword, userPassword);
}
bool StdinPDFDocBuilder::supports(const GooString &uri)
{
- if (uri.cmpN("fd://0", 6) == 0) {
- return true;
- } else {
- return false;
- }
+ return parseFdFromUri(uri) != -1;
}
diff --git a/poppler/StdinPDFDocBuilder.h b/poppler/StdinPDFDocBuilder.h
index a4bbf8e4..76c69ef1 100644
--- a/poppler/StdinPDFDocBuilder.h
+++ b/poppler/StdinPDFDocBuilder.h
@@ -18,7 +18,7 @@
//------------------------------------------------------------------------
// StdinPDFDocBuilder
//
-// The StdinPDFDocBuilder implements a PDFDocBuilder that read from stdin.
+// The StdinPDFDocBuilder implements a PDFDocBuilder that read from a file descriptor.
//------------------------------------------------------------------------
class StdinPDFDocBuilder : public PDFDocBuilder
@@ -27,6 +27,9 @@ class StdinPDFDocBuilder : public PDFDocBuilder
public:
std::unique_ptr<PDFDoc> buildPDFDoc(const GooString &uri, GooString *ownerPassword = nullptr, GooString *userPassword = nullptr, void *guiDataA = nullptr) override;
bool supports(const GooString &uri) override;
+
+private:
+ int parseFdFromUri(const GooString &uri);
};
#endif /* STDINPDFDOCBUILDER_H */
commit dc50059c757ae5c58b45755dc4f035e620679252
Author: Christian Persch <chpe at src.gnome.org>
Date: Sat Nov 13 11:03:48 2021 +0100
poppler: Export StdinCacheLoader and FileStream
They will be used in glib/ in a subsequent commit.
diff --git a/poppler/StdinCachedFile.h b/poppler/StdinCachedFile.h
index 7c12e1bf..7ce6dbc2 100644
--- a/poppler/StdinCachedFile.h
+++ b/poppler/StdinCachedFile.h
@@ -14,7 +14,7 @@
#include "CachedFile.h"
-class StdinCacheLoader : public CachedFileLoader
+class POPPLER_PRIVATE_EXPORT StdinCacheLoader : public CachedFileLoader
{
public:
diff --git a/poppler/Stream.h b/poppler/Stream.h
index 97ce5ea0..0ab56b6e 100644
--- a/poppler/Stream.h
+++ b/poppler/Stream.h
@@ -516,7 +516,7 @@ private:
#define fileStreamBufSize 256
-class FileStream : public BaseStream
+class POPPLER_PRIVATE_EXPORT FileStream : public BaseStream
{
public:
FileStream(GooFile *fileA, Goffset startA, bool limitedA, Goffset lengthA, Object &&dictA);
commit b01d37e14138de096212ae283840b580718966e7
Author: Christian Persch <chpe at src.gnome.org>
Date: Sat Nov 13 11:03:48 2021 +0100
gfile: Add GooFile constructor taking a file descriptor
diff --git a/goo/gfile.cc b/goo/gfile.cc
index 98fe7b7f..98e1a2f9 100644
--- a/goo/gfile.cc
+++ b/goo/gfile.cc
@@ -404,7 +404,12 @@ GooFile *GooFile::open(const std::string &fileName)
{
int fd = openFileDescriptor(fileName.c_str(), O_RDONLY);
- return fd < 0 ? nullptr : new GooFile(fd);
+ return GooFile::open(fd);
+}
+
+GooFile *GooFile::open(int fdA)
+{
+ return fdA < 0 ? nullptr : new GooFile(fdA);
}
GooFile::GooFile(int fdA) : fd(fdA)
diff --git a/goo/gfile.h b/goo/gfile.h
index d04b9ac6..a3650a4e 100644
--- a/goo/gfile.h
+++ b/goo/gfile.h
@@ -123,6 +123,9 @@ public:
Goffset size() const;
static GooFile *open(const std::string &fileName);
+#ifndef _WIN32
+ static GooFile *open(int fdA);
+#endif
#ifdef _WIN32
static GooFile *open(const wchar_t *fileName);
More information about the poppler
mailing list