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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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);
