1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-07-18 19:41:01 -05:00

Generalise strbuf_catf() into put_fmt().

marshal.h now provides a macro put_fmt() which allows you to write
arbitrary printf-formatted data to an arbitrary BinarySink.

We already had this facility for strbufs in particular, in the form of
strbuf_catf(). That was able to take advantage of knowing the inner
structure of a strbuf to minimise memory allocation (it would snprintf
directly into the strbuf's existing buffer if possible). For a general
black-box BinarySink we can't do that, so instead we dupvprintf into a
temporary buffer.

For consistency, I've removed strbuf_catf, and converted all uses of
it into the new put_fmt - and I've also added an extra vtable method
in the BinarySink API, so that put_fmt can still use strbuf_catf's
more efficient memory management when talking to a strbuf, and fall
back to the simpler strategy when that's not available.
This commit is contained in:
Simon Tatham
2021-11-19 10:23:32 +00:00
parent efee4e0eae
commit be8d3974ff
24 changed files with 217 additions and 193 deletions

View File

@ -4,6 +4,7 @@
#include "defs.h"
#include <stdio.h>
#include <stdarg.h>
/*
* A sort of 'abstract base class' or 'interface' or 'trait' which is
@ -12,6 +13,7 @@
*/
struct BinarySink {
void (*write)(BinarySink *sink, const void *data, size_t len);
void (*writefmtv)(BinarySink *sink, const char *fmt, va_list ap);
BinarySink *binarysink_;
};
@ -25,6 +27,7 @@ struct BinarySink {
#define BinarySink_IMPLEMENTATION BinarySink binarysink_[1]
#define BinarySink_INIT(obj, writefn) \
((obj)->binarysink_->write = (writefn), \
(obj)->binarysink_->writefmtv = NULL, \
(obj)->binarysink_->binarysink_ = (obj)->binarysink_)
/*
@ -139,6 +142,12 @@ struct BinarySink {
#define put_datapl(bs, pl) \
BinarySink_put_datapl(BinarySink_UPCAST(bs), pl)
/* Emit printf-formatted data, with no terminator. */
#define put_fmt(bs, ...) \
BinarySink_put_fmt(BinarySink_UPCAST(bs), __VA_ARGS__)
#define put_fmtv(bs, fmt, ap) \
BinarySink_put_fmtv(BinarySink_UPCAST(bs), fmt, ap)
/*
* The underlying real C functions that implement most of those
* macros. Generally you won't want to call these directly, because
@ -166,6 +175,8 @@ void BinarySink_put_asciz(BinarySink *, const char *str);
bool BinarySink_put_pstring(BinarySink *, const char *str);
void BinarySink_put_mp_ssh1(BinarySink *bs, mp_int *x);
void BinarySink_put_mp_ssh2(BinarySink *bs, mp_int *x);
void BinarySink_put_fmt(BinarySink *, const char *fmt, ...) PRINTF_LIKE(2, 3);
void BinarySink_put_fmtv(BinarySink *, const char *fmt, va_list ap);
/* ---------------------------------------------------------------------- */