diff options
author | Paul Gardiner <paul.gardiner@artifex.com> | 2018-01-04 15:11:24 +0000 |
---|---|---|
committer | Paul Gardiner <paul.gardiner@artifex.com> | 2018-01-19 13:52:25 +0000 |
commit | 457873fbf7fd6d40242722f3a51b41428302d0ca (patch) | |
tree | 2539ea3bc1490012f5f5bd95d0f9064d999eca04 | |
parent | 371890461adeff0bcc8d4986f666c59055bebc70 (diff) | |
download | mupdf-457873fbf7fd6d40242722f3a51b41428302d0ca.tar.xz |
Add fz_output_as_stream
This provides a way for some output streams to also be read, a feature
needed for the sake of document signing. Currently this is supported only
for file output.
-rw-r--r-- | include/mupdf/fitz/output.h | 19 | ||||
-rw-r--r-- | source/fitz/fitz-imp.h | 4 | ||||
-rw-r--r-- | source/fitz/output.c | 22 | ||||
-rw-r--r-- | source/fitz/stream-open.c | 8 |
4 files changed, 51 insertions, 2 deletions
diff --git a/include/mupdf/fitz/output.h b/include/mupdf/fitz/output.h index 0425e353..2530be47 100644 --- a/include/mupdf/fitz/output.h +++ b/include/mupdf/fitz/output.h @@ -5,6 +5,7 @@ #include "mupdf/fitz/context.h" #include "mupdf/fitz/buffer.h" #include "mupdf/fitz/string-util.h" +#include "mupdf/fitz/stream.h" /* Generic output streams - generalise between outputting to a file, @@ -62,6 +63,13 @@ typedef void (fz_output_close_fn)(fz_context *ctx, void *state); */ typedef void (fz_output_drop_fn)(fz_context *ctx, void *state); +/* + fz_stream_from_output_fn: A function type for use when implementing + fz_outputs. The supplied function of this type is called + when the fz_stream_from_output is called. +*/ +typedef fz_stream *(fz_stream_from_output_fn)(fz_context *ctx, void *state); + struct fz_output_s { @@ -71,6 +79,7 @@ struct fz_output_s fz_output_tell_fn *tell; fz_output_close_fn *close; fz_output_drop_fn *drop; + fz_stream_from_output_fn *as_stream; }; /* @@ -172,6 +181,16 @@ void fz_close_output(fz_context *, fz_output *); void fz_drop_output(fz_context *, fz_output *); /* + fz_stream_from_output: obtain the fz_output in the form of a fz_stream + + This allows data to be read back from some forms of fz_output object. + When finished reading, the fz_stream should be released by calling + fz_drop_stream. Until the fz_stream is dropped, no further operations + should be performed on the fz_output object. +*/ +fz_stream *fz_stream_from_output(fz_context *, fz_output *); + +/* fz_write_data: Write data to output. data: Pointer to data to write. diff --git a/source/fitz/fitz-imp.h b/source/fitz/fitz-imp.h index 41c905e4..9740213d 100644 --- a/source/fitz/fitz-imp.h +++ b/source/fitz/fitz-imp.h @@ -3,6 +3,8 @@ #include "mupdf/fitz.h" +#include <stdio.h> + struct fz_buffer_s { int refs; @@ -91,6 +93,8 @@ void fz_new_output_context(fz_context *ctx); void fz_drop_output_context(fz_context *ctx); fz_output_context *fz_keep_output_context(fz_context *ctx); +fz_stream *fz_open_file_ptr_no_close(fz_context *ctx, FILE *file); + #if defined(MEMENTO) || !defined(NDEBUG) #define FITZ_DEBUG_LOCKING #endif diff --git a/source/fitz/output.c b/source/fitz/output.c index 4c6aa6b4..18791603 100644 --- a/source/fitz/output.c +++ b/source/fitz/output.c @@ -158,6 +158,14 @@ file_drop(fz_context *ctx, void *opaque) fz_warn(ctx, "cannot fclose: %s", strerror(errno)); } +static fz_stream * +file_as_stream(fz_context *ctx, void *opaque) +{ + FILE *file = opaque; + fflush(file); + return fz_open_file_ptr_no_close(ctx, file); +}; + fz_output * fz_new_output(fz_context *ctx, void *state, fz_output_write_fn *write, fz_output_close_fn *close, fz_output_drop_fn *drop) { @@ -197,7 +205,7 @@ fz_new_output_with_path(fz_context *ctx, const char *filename, int append) if (errno != ENOENT) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot remove file '%s': %s", filename, strerror(errno)); } - file = fz_fopen_utf8(filename, append ? "ab" : "wb"); + file = fz_fopen_utf8(filename, "rb+"); #else /* Ensure we create a brand new file. We don't want to clobber our old file. */ if (!append) @@ -206,7 +214,7 @@ fz_new_output_with_path(fz_context *ctx, const char *filename, int append) if (errno != ENOENT) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot remove file '%s': %s", filename, strerror(errno)); } - file = fopen(filename, append ? "ab" : "wb"); + file = fopen(filename, "rb+"); #endif if (!file) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot open file '%s': %s", filename, strerror(errno)); @@ -214,6 +222,7 @@ fz_new_output_with_path(fz_context *ctx, const char *filename, int append) out = fz_new_output(ctx, file, file_write, NULL, file_drop); out->seek = file_seek; out->tell = file_tell; + out->as_stream = file_as_stream; return out; } @@ -293,6 +302,15 @@ fz_tell_output(fz_context *ctx, fz_output *out) return out->tell(ctx, out->state); } +fz_stream * +fz_stream_from_output(fz_context *ctx, fz_output *out) +{ + if (!out) return 0; + if (out->as_stream == NULL) + fz_throw(ctx, FZ_ERROR_GENERIC, "Cannot derive input stream from output stream"); + return out->as_stream(ctx, out->state); +} + static void fz_write_emit(fz_context *ctx, void *out, int c) { diff --git a/source/fitz/stream-open.c b/source/fitz/stream-open.c index ffd61b66..1a99ad52 100644 --- a/source/fitz/stream-open.c +++ b/source/fitz/stream-open.c @@ -144,6 +144,14 @@ fz_open_file_ptr(fz_context *ctx, FILE *file) return stm; } +fz_stream *fz_open_file_ptr_no_close(fz_context *ctx, FILE *file) +{ + fz_stream *stm = fz_open_file_ptr(ctx, file); + /* We don't own the file ptr. Ensure we don't close it */ + stm->close = NULL; + return stm; +} + fz_stream * fz_open_file(fz_context *ctx, const char *name) { |