diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2015-11-09 14:17:00 +0100 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2015-12-11 12:11:31 +0100 |
commit | c22e6a6dc2bf6acbac955bd5fbdd896329dfd725 (patch) | |
tree | d9d84d3a6a74ed74c9d470b532097769545e8dc6 /source/fitz/output.c | |
parent | 95b928431f233052e4bbbd1b2bf9fc705657b5a7 (diff) | |
download | mupdf-c22e6a6dc2bf6acbac955bd5fbdd896329dfd725.tar.xz |
Use fz_output instead of FILE* for most of our output needs.
Use fz_output in debug printing functions.
Use fz_output in pdfshow.
Use fz_output in fz_trace_device instead of stdout.
Use fz_output in pdf-write.c.
Rename fz_new_output_to_filename to fz_new_output_with_path.
Add seek and tell to fz_output.
Remove unused functions like fz_fprintf.
Fix typo in pdf_print_obj.
Diffstat (limited to 'source/fitz/output.c')
-rw-r--r-- | source/fitz/output.c | 183 |
1 files changed, 113 insertions, 70 deletions
diff --git a/source/fitz/output.c b/source/fitz/output.c index 027f66c3..e39dd352 100644 --- a/source/fitz/output.c +++ b/source/fitz/output.c @@ -3,61 +3,74 @@ struct fz_output_s { void *opaque; - int (*printf)(fz_context *, void *opaque, const char *, va_list ap); int (*write)(fz_context *, void *opaque, const void *, int n); + void (*seek)(fz_context *, void *opaque, fz_off_t off, int whence); + fz_off_t (*tell)(fz_context *, void *opaque); void (*close)(fz_context *, void *opaque); }; static int -file_printf(fz_context *ctx, void *opaque, const char *fmt, va_list ap) +file_write(fz_context *ctx, void *opaque, const void *buffer, int count) { FILE *file = opaque; - return fz_vfprintf(ctx, file, fmt, ap); + size_t n = fwrite(buffer, 1, count, file); + if (n < count && ferror(file)) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot fwrite: %s", strerror(errno)); + return n; } -static int -file_write(fz_context *ctx, void *opaque, const void *buffer, int count) +static void +file_seek(fz_context *ctx, void *opaque, fz_off_t off, int whence) { FILE *file = opaque; - return fwrite(buffer, 1, count, file); + int n = fz_fseek(file, off, whence); + if (n < 0) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot fseek: %s", strerror(errno)); +} + +static fz_off_t +file_tell(fz_context *ctx, void *opaque) +{ + FILE *file = opaque; + fz_off_t off = fz_ftell(file); + if (off == -1) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot ftell: %s", strerror(errno)); + return off; } static void file_close(fz_context *ctx, void *opaque) { FILE *file = opaque; - fclose(file); + int n = fclose(file); + if (n < 0) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot fclose: %s", strerror(errno)); } fz_output * -fz_new_output_with_file(fz_context *ctx, FILE *file, int close) +fz_new_output_with_file_ptr(fz_context *ctx, FILE *file, int close) { fz_output *out = fz_malloc_struct(ctx, fz_output); out->opaque = file; - out->printf = file_printf; out->write = file_write; + out->seek = file_seek; + out->tell = file_tell; out->close = close ? file_close : NULL; return out; } fz_output * -fz_new_output_to_filename(fz_context *ctx, const char *filename) +fz_new_output_with_path(fz_context *ctx, const char *filename, int append) { fz_output *out = NULL; - FILE *file = fz_fopen(filename, "wb"); + FILE *file = fz_fopen(filename, append ? "ab" : "wb"); if (!file) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot open file '%s': %s", filename, strerror(errno)); - fz_var(ctx); - fz_try(ctx) { - out = fz_malloc_struct(ctx, fz_output); - out->opaque = file; - out->printf = file_printf; - out->write = file_write; - out->close = file_close; + out = fz_new_output_with_file_ptr(ctx, file, 1); } fz_catch(ctx) { @@ -67,84 +80,114 @@ fz_new_output_to_filename(fz_context *ctx, const char *filename) return out; } -void -fz_drop_output(fz_context *ctx, fz_output *out) +static int +buffer_write(fz_context *ctx, void *opaque, const void *data, int len) { - if (!out) - return; - if (out->close) - out->close(ctx, out->opaque); - fz_free(ctx, out); + fz_buffer *buffer = opaque; + fz_write_buffer(ctx, buffer, (unsigned char *)data, len); + return len; } -int -fz_printf(fz_context *ctx, fz_output *out, const char *fmt, ...) +static void +buffer_seek(fz_context *ctx, void *opaque, fz_off_t off, int whence) { - int ret; - va_list ap; - - if (!out) - return 0; + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot seek in buffer: %s", strerror(errno)); +} - va_start(ap, fmt); - ret = out->printf(ctx, out->opaque, fmt, ap); - va_end(ap); +static fz_off_t +buffer_tell(fz_context *ctx, void *opaque) +{ + fz_buffer *buffer = opaque; + return buffer->len; +} - return ret; +static void +buffer_close(fz_context *ctx, void *opaque) +{ + fz_buffer *buffer = opaque; + fz_drop_buffer(ctx, buffer); } -int -fz_write(fz_context *ctx, fz_output *out, const void *data, int len) +fz_output * +fz_new_output_with_buffer(fz_context *ctx, fz_buffer *buf) { - if (!out) - return 0; - return out->write(ctx, out->opaque, data, len); + fz_output *out = fz_malloc_struct(ctx, fz_output); + out->opaque = fz_keep_buffer(ctx, buf); + out->write = buffer_write; + out->seek = buffer_seek; + out->tell = buffer_tell; + out->close = buffer_close; + return out; } void -fz_putc(fz_context *ctx, fz_output *out, char c) +fz_drop_output(fz_context *ctx, fz_output *out) { - if (out) - (void)out->write(ctx, out->opaque, &c, 1); + if (!out) return; + if (out->close) + out->close(ctx, out->opaque); + fz_free(ctx, out); } -int -fz_puts(fz_context *ctx, fz_output *out, const char *str) +void +fz_seek_output(fz_context *ctx, fz_output *out, fz_off_t off, int whence) { - if (!out) - return 0; - return out->write(ctx, out->opaque, str, strlen(str)); + if (!out) return; + out->seek(ctx, out->opaque, off, whence); } -static int -buffer_printf(fz_context *ctx, void *opaque, const char *fmt, va_list list) +fz_off_t +fz_tell_output(fz_context *ctx, fz_output *out) { - fz_buffer *buffer = opaque; - return fz_buffer_vprintf(ctx, buffer, fmt, list); + if (!out) return 0; + return out->tell(ctx, out->opaque); } -static int -buffer_write(fz_context *ctx, void *opaque, const void *data, int len) +void +fz_vprintf(fz_context *ctx, fz_output *out, const char *fmt, va_list old_args) { - fz_buffer *buffer = opaque; - fz_write_buffer(ctx, buffer, (unsigned char *)data, len); - return len; + char buffer[256], *p = buffer; + int len; + va_list args; + + if (!out) return; + + /* First try using our fixed size buffer */ + va_copy(args, old_args); + len = fz_vsnprintf(buffer, sizeof buffer, fmt, args); + va_copy_end(args); + + /* If that failed, allocate a big enough buffer */ + if (len >= sizeof buffer) + { + p = fz_malloc(ctx, len + 1); + va_copy(args, old_args); + fz_vsnprintf(p, len + 1, fmt, args); + va_copy_end(args); + } + + fz_try(ctx) + out->write(ctx, out->opaque, p, len); + fz_always(ctx) + if (p != buffer) + fz_free(ctx, p); + fz_catch(ctx) + fz_rethrow(ctx); } -static void -buffer_close(fz_context *ctx, void *opaque) +void +fz_printf(fz_context *ctx, fz_output *out, const char *fmt, ...) { - fz_buffer *buffer = opaque; - fz_drop_buffer(ctx, buffer); + va_list args; + if (!out) return; + va_start(args, fmt); + fz_vprintf(ctx, out, fmt, args); + va_end(args); } -fz_output * -fz_new_output_with_buffer(fz_context *ctx, fz_buffer *buf) +int +fz_write(fz_context *ctx, fz_output *out, const void *data, int len) { - fz_output *out = fz_malloc_struct(ctx, fz_output); - out->opaque = fz_keep_buffer(ctx, buf); - out->printf = buffer_printf; - out->write = buffer_write; - out->close = buffer_close; - return out; + if (!out) return 0; + return out->write(ctx, out->opaque, data, len); } |