Commit 31d9c24b33b28155001f80f11bdb576cd366c207

Edward Thomson 2021-05-06T16:32:14

filter: internal git_buf filter handling function Introduce `git_filter_list__convert_buf` which behaves like the old implementation of `git_filter_list__apply_data`, where it might move the input data buffer over into the output data buffer space for efficiency. This new implementation will do so in a more predictible way, always freeing the given input buffer (either moving it to the output buffer or filtering it into the output buffer first). Convert internal users to it.

diff --git a/src/checkout.c b/src/checkout.c
index cadc4c8..f69b302 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -2121,7 +2121,7 @@ static int checkout_write_merge(
 		if ((error = git_filter_list__load_ext(
 				&fl, data->repo, NULL, git_buf_cstr(&path_workdir),
 				GIT_FILTER_TO_WORKTREE, &filter_opts)) < 0 ||
-			(error = git_filter_list_apply_to_data(&out_data, fl, &in_data)) < 0)
+			(error = git_filter_list__convert_buf(&out_data, fl, &in_data)) < 0)
 			goto done;
 	} else {
 		out_data.ptr = (char *)result.ptr;
diff --git a/src/diff_file.c b/src/diff_file.c
index 2116f00..eeaf4a5 100644
--- a/src/diff_file.c
+++ b/src/diff_file.c
@@ -362,10 +362,7 @@ static int diff_file_content_load_workdir_file(
 	if (!(error = git_futils_readbuffer_fd(&raw, fd, (size_t)fc->file->size))) {
 		git_buf out = GIT_BUF_INIT;
 
-		error = git_filter_list_apply_to_data(&out, fl, &raw);
-
-		if (out.ptr != raw.ptr)
-			git_buf_dispose(&raw);
+		error = git_filter_list__convert_buf(&out, fl, &raw);
 
 		if (!error) {
 			fc->map.len  = out.size;
diff --git a/src/filter.c b/src/filter.c
index 200d705..6c09a6a 100644
--- a/src/filter.c
+++ b/src/filter.c
@@ -742,6 +742,28 @@ int git_filter_list_apply_to_buffer(
 	return error;
 }
 
+int git_filter_list__convert_buf(
+	git_buf *out,
+	git_filter_list *filters,
+	git_buf *in)
+{
+	int error;
+
+	if (!filters || git_filter_list_length(filters) == 0) {
+		git_buf_swap(out, in);
+		git_buf_dispose(in);
+		return 0;
+	}
+
+	error = git_filter_list_apply_to_buffer(out, filters,
+		in->ptr, in->size);
+
+	if (!error)
+		git_buf_dispose(in);
+
+	return error;
+}
+
 int git_filter_list_apply_to_file(
 	git_buf *out,
 	git_filter_list *filters,
diff --git a/src/filter.h b/src/filter.h
index 34081fb..bbc4c0f 100644
--- a/src/filter.h
+++ b/src/filter.h
@@ -36,6 +36,15 @@ extern int git_filter_list__load_ext(
 	git_filter_options *filter_opts);
 
 /*
+ * The given input buffer will be converted to the given output buffer.
+ * The input buffer will be freed (_if_ it was allocated).
+ */
+extern int git_filter_list__convert_buf(
+	git_buf *out,
+	git_filter_list *filters,
+	git_buf *in);
+
+/*
  * Available filters
  */
 
diff --git a/src/odb.c b/src/odb.c
index b2988c4..1b91434 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -260,9 +260,7 @@ int git_odb__hashfd_filtered(
 	if (!(error = git_futils_readbuffer_fd(&raw, fd, size))) {
 		git_buf post = GIT_BUF_INIT;
 
-		error = git_filter_list_apply_to_data(&post, fl, &raw);
-
-		git_buf_dispose(&raw);
+		error = git_filter_list__convert_buf(&post, fl, &raw);
 
 		if (!error)
 			error = git_odb_hash(out, post.ptr, post.size, type);