diff --git a/defs.h b/defs.h index 286e0c96..d7e2f338 100644 --- a/defs.h +++ b/defs.h @@ -91,6 +91,7 @@ typedef struct BinarySink BinarySink; typedef struct BinarySource BinarySource; typedef struct stdio_sink stdio_sink; typedef struct bufchain_sink bufchain_sink; +typedef struct buffer_sink buffer_sink; typedef struct handle_sink handle_sink; typedef struct IdempotentCallback IdempotentCallback; diff --git a/marshal.h b/marshal.h index b9136292..34a0572f 100644 --- a/marshal.h +++ b/marshal.h @@ -353,7 +353,14 @@ struct bufchain_sink { bufchain *ch; BinarySink_IMPLEMENTATION; }; +struct buffer_sink { + char *out; + size_t space; + bool overflowed; + BinarySink_IMPLEMENTATION; +}; void stdio_sink_init(stdio_sink *sink, FILE *fp); void bufchain_sink_init(bufchain_sink *sink, bufchain *ch); +void buffer_sink_init(buffer_sink *sink, void *buffer, size_t len); #endif /* PUTTY_MARSHAL_H */ diff --git a/utils/marshal.c b/utils/marshal.c index 534ecf50..ec6a5806 100644 --- a/utils/marshal.c +++ b/utils/marshal.c @@ -336,3 +336,23 @@ void bufchain_sink_init(bufchain_sink *sink, bufchain *ch) sink->ch = ch; BinarySink_INIT(sink, bufchain_sink_write); } + +static void buffer_sink_write(BinarySink *bs, const void *data, size_t len) +{ + buffer_sink *sink = BinarySink_DOWNCAST(bs, buffer_sink); + if (len > sink->space) { + len = sink->space; + sink->overflowed = true; + } + memcpy(sink->out, data, len); + sink->space -= len; + sink->out += len; +} + +void buffer_sink_init(buffer_sink *sink, void *buffer, size_t len) +{ + sink->out = buffer; + sink->space = len; + sink->overflowed = false; + BinarySink_INIT(sink, buffer_sink_write); +}