Commit a8943c04 by Edward Thomson

filter: proxy_stream is now git_filter_buffered_stream

The filter's proxy_stream is used to adapt filters that only provided an
`apply` function into a `stream` function.  Make this internal to the
library instead of private to the filter file.  This will allow the
filters to use it directly, instead of relying on the filter
functionality to do the proxying.
parent a9a7bfb5
......@@ -839,9 +839,10 @@ int git_filter_list_apply_to_blob(
return error;
}
struct proxy_stream {
struct buffered_stream {
git_writestream parent;
git_filter *filter;
int (*write_fn)(git_filter *, void **, git_buf *, const git_buf *, const git_filter_source *);
const git_filter_source *source;
void **payload;
git_buf input;
......@@ -850,89 +851,91 @@ struct proxy_stream {
git_writestream *target;
};
static int proxy_stream_write(
static int buffered_stream_write(
git_writestream *s, const char *buffer, size_t len)
{
struct proxy_stream *proxy_stream = (struct proxy_stream *)s;
GIT_ASSERT_ARG(proxy_stream);
struct buffered_stream *buffered_stream = (struct buffered_stream *)s;
GIT_ASSERT_ARG(buffered_stream);
return git_buf_put(&proxy_stream->input, buffer, len);
return git_buf_put(&buffered_stream->input, buffer, len);
}
static int proxy_stream_close(git_writestream *s)
static int buffered_stream_close(git_writestream *s)
{
struct proxy_stream *proxy_stream = (struct proxy_stream *)s;
struct buffered_stream *buffered_stream = (struct buffered_stream *)s;
git_buf *writebuf;
git_error_state error_state = {0};
int error;
GIT_ASSERT_ARG(proxy_stream);
GIT_ASSERT_ARG(buffered_stream);
error = proxy_stream->filter->apply(
proxy_stream->filter,
proxy_stream->payload,
proxy_stream->output,
&proxy_stream->input,
proxy_stream->source);
error = buffered_stream->write_fn(
buffered_stream->filter,
buffered_stream->payload,
buffered_stream->output,
&buffered_stream->input,
buffered_stream->source);
if (error == GIT_PASSTHROUGH) {
writebuf = &proxy_stream->input;
writebuf = &buffered_stream->input;
} else if (error == 0) {
if ((error = git_buf_sanitize(proxy_stream->output)) < 0)
if ((error = git_buf_sanitize(buffered_stream->output)) < 0)
return error;
writebuf = proxy_stream->output;
writebuf = buffered_stream->output;
} else {
/* close stream before erroring out taking care
* to preserve the original error */
git_error_state_capture(&error_state, error);
proxy_stream->target->close(proxy_stream->target);
buffered_stream->target->close(buffered_stream->target);
git_error_state_restore(&error_state);
return error;
}
if ((error = proxy_stream->target->write(
proxy_stream->target, writebuf->ptr, writebuf->size)) == 0)
error = proxy_stream->target->close(proxy_stream->target);
if ((error = buffered_stream->target->write(
buffered_stream->target, writebuf->ptr, writebuf->size)) == 0)
error = buffered_stream->target->close(buffered_stream->target);
return error;
}
static void proxy_stream_free(git_writestream *s)
static void buffered_stream_free(git_writestream *s)
{
struct proxy_stream *proxy_stream = (struct proxy_stream *)s;
struct buffered_stream *buffered_stream = (struct buffered_stream *)s;
if (proxy_stream) {
git_buf_dispose(&proxy_stream->input);
git_buf_dispose(&proxy_stream->temp_buf);
git__free(proxy_stream);
if (buffered_stream) {
git_buf_dispose(&buffered_stream->input);
git_buf_dispose(&buffered_stream->temp_buf);
git__free(buffered_stream);
}
}
static int proxy_stream_init(
int git_filter_buffered_stream_new(
git_writestream **out,
git_filter *filter,
int (*write_fn)(git_filter *, void **, git_buf *, const git_buf *, const git_filter_source *),
git_buf *temp_buf,
void **payload,
const git_filter_source *source,
git_writestream *target)
{
struct proxy_stream *proxy_stream = git__calloc(1, sizeof(struct proxy_stream));
GIT_ERROR_CHECK_ALLOC(proxy_stream);
proxy_stream->parent.write = proxy_stream_write;
proxy_stream->parent.close = proxy_stream_close;
proxy_stream->parent.free = proxy_stream_free;
proxy_stream->filter = filter;
proxy_stream->payload = payload;
proxy_stream->source = source;
proxy_stream->target = target;
proxy_stream->output = temp_buf ? temp_buf : &proxy_stream->temp_buf;
struct buffered_stream *buffered_stream = git__calloc(1, sizeof(struct buffered_stream));
GIT_ERROR_CHECK_ALLOC(buffered_stream);
buffered_stream->parent.write = buffered_stream_write;
buffered_stream->parent.close = buffered_stream_close;
buffered_stream->parent.free = buffered_stream_free;
buffered_stream->filter = filter;
buffered_stream->write_fn = write_fn;
buffered_stream->output = temp_buf ? temp_buf : &buffered_stream->temp_buf;
buffered_stream->payload = payload;
buffered_stream->source = source;
buffered_stream->target = target;
if (temp_buf)
git_buf_clear(temp_buf);
*out = (git_writestream *)proxy_stream;
*out = (git_writestream *)buffered_stream;
return 0;
}
......@@ -970,9 +973,9 @@ static int stream_list_init(
&fe->payload, &filters->source, last_stream);
else
/* Create a stream that proxies the one-shot apply */
error = proxy_stream_init(&filter_stream, fe->filter,
filters->temp_buf, &fe->payload, &filters->source,
last_stream);
error = git_filter_buffered_stream_new(&filter_stream,
fe->filter, fe->filter->apply, filters->temp_buf,
&fe->payload, &filters->source, last_stream);
if (error < 0)
goto out;
......
......@@ -11,6 +11,7 @@
#include "attr_file.h"
#include "git2/filter.h"
#include "git2/sys/filter.h"
/* Amount of file to examine for NUL byte when checking binary-ness */
#define GIT_FILTER_BYTES_TO_CHECK_NUL 8000
......@@ -51,4 +52,13 @@ extern int git_filter_list__convert_buf(
extern git_filter *git_crlf_filter_new(void);
extern git_filter *git_ident_filter_new(void);
extern int git_filter_buffered_stream_new(
git_writestream **out,
git_filter *filter,
int (*write_fn)(git_filter *, void **, git_buf *, const git_buf *, const git_filter_source *),
git_buf *temp_buf,
void **payload,
const git_filter_source *source,
git_writestream *target);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment