summaryrefslogtreecommitdiff
path: root/source/fitz
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2017-03-15 16:27:15 +0100
committerTor Andersson <tor.andersson@artifex.com>2017-03-22 12:07:26 +0100
commite013fd7d0f5ae8f5c994aad4d02f5169946f1a26 (patch)
treebe8a7c8006b1e22a04d70c8db9bb95120b1c7f3a /source/fitz
parent8e791ab5cd73dc783aded93f2dd7c77d89623fe8 (diff)
downloadmupdf-e013fd7d0f5ae8f5c994aad4d02f5169946f1a26.tar.xz
Simplify string formatter API.
Emit characters with callbacks so we don't need to do two passes using vsnprintf to count, format, and copy the result.
Diffstat (limited to 'source/fitz')
-rw-r--r--source/fitz/buffer.c41
-rw-r--r--source/fitz/output.c37
-rw-r--r--source/fitz/printf.c74
3 files changed, 74 insertions, 78 deletions
diff --git a/source/fitz/buffer.c b/source/fitz/buffer.c
index ab814728..d432e810 100644
--- a/source/fitz/buffer.c
+++ b/source/fitz/buffer.c
@@ -331,45 +331,24 @@ fz_append_bits_pad(fz_context *ctx, fz_buffer *buf)
buf->unused_bits = 0;
}
-size_t
+static void fz_append_emit(fz_context *ctx, void *buffer, int c)
+{
+ fz_append_byte(ctx, buffer, c);
+}
+
+void
fz_append_printf(fz_context *ctx, fz_buffer *buffer, const char *fmt, ...)
{
- size_t ret;
va_list args;
va_start(args, fmt);
- ret = fz_append_vprintf(ctx, buffer, fmt, args);
+ fz_format_string(ctx, buffer, fz_append_emit, fmt, args);
va_end(args);
- return ret;
}
-size_t
-fz_append_vprintf(fz_context *ctx, fz_buffer *buffer, const char *fmt, va_list old_args)
+void
+fz_append_vprintf(fz_context *ctx, fz_buffer *buffer, const char *fmt, va_list args)
{
- size_t slack;
- size_t len;
- va_list args;
-
- slack = buffer->cap - buffer->len;
- va_copy(args, old_args);
- len = fz_vsnprintf((char *)buffer->data + buffer->len, slack, fmt, args);
- va_copy_end(args);
-
- /* len is the number of characters in the formatted string (not including
- * the terminating zero), so if (len > slack) the string was truncated. */
- if (len > slack)
- {
- /* Grow the buffer and retry */
- fz_ensure_buffer(ctx, buffer, buffer->len + len);
- slack = buffer->cap - buffer->len;
-
- va_copy(args, old_args);
- len = fz_vsnprintf((char *)buffer->data + buffer->len, slack, fmt, args);
- va_copy_end(args);
- }
-
- buffer->len += len;
-
- return len;
+ fz_format_string(ctx, buffer, fz_append_emit, fmt, args);
}
void
diff --git a/source/fitz/output.c b/source/fitz/output.c
index bd4dba66..961bafe5 100644
--- a/source/fitz/output.c
+++ b/source/fitz/output.c
@@ -266,36 +266,17 @@ fz_tell_output(fz_context *ctx, fz_output *out)
return out->tell(ctx, out->state);
}
-void
-fz_write_vprintf(fz_context *ctx, fz_output *out, const char *fmt, va_list old_args)
+static void
+fz_write_emit(fz_context *ctx, void *out, int c)
{
- char buffer[256], *p = buffer;
- size_t len;
- va_list args;
+ fz_write_byte(ctx, out, c);
+}
+void
+fz_write_vprintf(fz_context *ctx, fz_output *out, const char *fmt, 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);
- va_copy(args, old_args);
- fz_vsnprintf(p, len, fmt, args);
- va_copy_end(args);
- }
-
- fz_try(ctx)
- out->write(ctx, out->state, p, len);
- fz_always(ctx)
- if (p != buffer)
- fz_free(ctx, p);
- fz_catch(ctx)
- fz_rethrow(ctx);
+ fz_format_string(ctx, out, fz_write_emit, fmt, args);
}
void
@@ -304,7 +285,7 @@ fz_write_printf(fz_context *ctx, fz_output *out, const char *fmt, ...)
va_list args;
if (!out) return;
va_start(args, fmt);
- fz_write_vprintf(ctx, out, fmt, args);
+ fz_format_string(ctx, out, fz_write_emit, fmt, args);
va_end(args);
}
diff --git a/source/fitz/printf.c b/source/fitz/printf.c
index 65c98278..d0f95327 100644
--- a/source/fitz/printf.c
+++ b/source/fitz/printf.c
@@ -4,16 +4,14 @@ static const char *fz_hex_digits = "0123456789abcdef";
struct fmtbuf
{
- char *p;
- size_t s;
- size_t n;
+ fz_context *ctx;
+ void *user;
+ void (*emit)(fz_context *ctx, void *user, int c);
};
-static void fmtputc(struct fmtbuf *out, int c)
+static inline void fmtputc(struct fmtbuf *out, int c)
{
- if (out->n < out->s)
- out->p[out->n] = c;
- ++(out->n);
+ out->emit(out->ctx, out->user, c);
}
/*
@@ -151,29 +149,31 @@ static void fmtquote(struct fmtbuf *out, const char *s, int sq, int eq)
fmtputc(out, eq);
}
-size_t
-fz_vsnprintf(char *buffer, size_t space, const char *fmt, va_list args)
+void
+fz_format_string(fz_context *ctx, void *user, void (*emit)(fz_context *ctx, void *user, int c), const char *fmt, va_list args)
{
struct fmtbuf out;
+ int c, i, n, z;
fz_matrix *m;
fz_rect *r;
fz_point *p;
- int c, i, n, z;
int64_t i64;
double f;
char *s;
size_t length;
- out.p = buffer;
- out.s = space;
- out.n = 0;
+ out.ctx = ctx;
+ out.user = user;
+ out.emit = emit;
while ((c = *fmt++) != 0)
{
- if (c == '%') {
+ if (c == '%')
+ {
c = *fmt++;
if (c == 0)
break;
+
z = 1;
if (c == '0' && fmt[0] && fmt[1]) {
z = *fmt++ - '0';
@@ -184,6 +184,7 @@ fz_vsnprintf(char *buffer, size_t space, const char *fmt, va_list args)
c = *fmt++;
}
}
+
/* Check for lengths */
length = 0;
switch (c) {
@@ -213,6 +214,7 @@ fz_vsnprintf(char *buffer, size_t space, const char *fmt, va_list args)
if (c == 0)
break; /* Can't warn :( */
}
+
switch (c) {
default:
fmtputc(&out, '%');
@@ -326,22 +328,56 @@ fz_vsnprintf(char *buffer, size_t space, const char *fmt, va_list args)
fmtquote(&out, s, '(', ')');
break;
}
- } else {
+ }
+ else
+ {
fmtputc(&out, c);
}
}
+}
- fmtputc(&out, 0);
+struct snprintf_buffer
+{
+ char *p;
+ size_t s, n;
+};
+
+static void snprintf_emit(fz_context *ctx, void *out_, int c)
+{
+ struct snprintf_buffer *out = out_;
+ if (out->n < out->s)
+ out->p[out->n] = c;
+ ++(out->n);
+}
+
+size_t
+fz_vsnprintf(char *buffer, size_t space, const char *fmt, va_list args)
+{
+ struct snprintf_buffer out;
+ out.p = buffer;
+ out.s = space;
+ out.n = 0;
+
+ /* Note: using a NULL context is safe here */
+ fz_format_string(NULL, &out, snprintf_emit, fmt, args);
+ snprintf_emit(NULL, &out, 0);
return out.n - 1;
}
size_t
fz_snprintf(char *buffer, size_t space, const char *fmt, ...)
{
- size_t n;
va_list ap;
+ struct snprintf_buffer out;
+ out.p = buffer;
+ out.s = space;
+ out.n = 0;
+
va_start(ap, fmt);
- n = fz_vsnprintf(buffer, space, fmt, ap);
+ /* Note: using a NULL context is safe here */
+ fz_format_string(NULL, &out, snprintf_emit, fmt, ap);
+ snprintf_emit(NULL, &out, 0);
va_end(ap);
- return n;
+
+ return out.n - 1;
}