Commit d4cf167515d3ed7b27c1358fc2e19b9caf66e8ad

Edward Thomson 2015-02-19T10:05:33

buffer: introduce git_buf_attach_notowned Provide a convenience function that creates a buffer that can be provided to callers but will not be freed via `git_buf_free`, so the buffer creator maintains the allocation lifecycle of the buffer's contents.

diff --git a/src/attr.c b/src/attr.c
index 44593da..3842080 100644
--- a/src/attr.c
+++ b/src/attr.c
@@ -282,9 +282,8 @@ static int system_attr_file(
 	 * a consumer. This allows them to treat this as a regular `git_buf`,
 	 * but their call to `git_buf_free` will not attempt to free it.
 	 */
-	out->ptr = attr_session->sysdir.ptr;
-	out->size = attr_session->sysdir.size;
-	out->asize = 0;
+	git_buf_attach_notowned(
+		out, attr_session->sysdir.ptr, attr_session->sysdir.size);
 	return 0;
 }
 
diff --git a/src/blob.c b/src/blob.c
index 30d5b70..ba8769c 100644
--- a/src/blob.c
+++ b/src/blob.c
@@ -329,15 +329,13 @@ cleanup:
 
 int git_blob_is_binary(const git_blob *blob)
 {
-	git_buf content;
+	git_buf content = GIT_BUF_INIT;
 
 	assert(blob);
 
-	content.ptr   = blob->odb_object->buffer;
-	content.size  =
-		min(blob->odb_object->cached.size, GIT_FILTER_BYTES_TO_CHECK_NUL);
-	content.asize = 0;
-
+	git_buf_attach_notowned(&content, blob->odb_object->buffer,
+		min(blob->odb_object->cached.size,
+		GIT_FILTER_BYTES_TO_CHECK_NUL));
 	return git_buf_text_is_binary(&content);
 }
 
diff --git a/src/buffer.c b/src/buffer.c
index 3deb032..f633c5e 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -500,6 +500,20 @@ void git_buf_attach(git_buf *buf, char *ptr, size_t asize)
 	}
 }
 
+void git_buf_attach_notowned(git_buf *buf, const char *ptr, size_t size)
+{
+	if (git_buf_is_allocated(buf))
+		git_buf_free(buf);
+
+	if (!size) {
+		git_buf_init(buf, 0);
+	} else {
+		buf->ptr = (char *)ptr;
+		buf->asize = 0;
+		buf->size = size;
+	}
+}
+
 int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...)
 {
 	va_list ap;
diff --git a/src/buffer.h b/src/buffer.h
index 52342e3..093ed9b 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -74,6 +74,12 @@ extern void git_buf_swap(git_buf *buf_a, git_buf *buf_b);
 extern char *git_buf_detach(git_buf *buf);
 extern void git_buf_attach(git_buf *buf, char *ptr, size_t asize);
 
+/* Populates a `git_buf` where the contents are not "owned" by the
+ * buffer, and calls to `git_buf_free` will not free the given buf.
+ */
+extern void git_buf_attach_notowned(
+	git_buf *buf, const char *ptr, size_t size);
+
 /**
  * Test if there have been any reallocation failures with this git_buf.
  *
diff --git a/src/diff_driver.c b/src/diff_driver.c
index 7313ab5..049e6ef 100644
--- a/src/diff_driver.c
+++ b/src/diff_driver.c
@@ -418,14 +418,13 @@ void git_diff_driver_update_options(
 int git_diff_driver_content_is_binary(
 	git_diff_driver *driver, const char *content, size_t content_len)
 {
-	git_buf search;
-
-	search.ptr   = (char *)content;
-	search.size  = min(content_len, GIT_FILTER_BYTES_TO_CHECK_NUL);
-	search.asize = 0;
+	git_buf search = GIT_BUF_INIT;
 
 	GIT_UNUSED(driver);
 
+	git_buf_attach_notowned(&search, content,
+		min(content_len, GIT_FILTER_BYTES_TO_CHECK_NUL));
+
 	/* TODO: provide encoding / binary detection callbacks that can
 	 * be UTF-8 aware, etc.  For now, instead of trying to be smart,
 	 * let's just use the simple NUL-byte detection that core git uses.
diff --git a/src/filter.c b/src/filter.c
index 08aa14b..4009a61 100644
--- a/src/filter.c
+++ b/src/filter.c
@@ -606,23 +606,6 @@ size_t git_filter_list_length(const git_filter_list *fl)
 	return fl ? git_array_size(fl->filters) : 0;
 }
 
-static int filter_list_out_buffer_from_raw(
-	git_buf *out, const void *ptr, size_t size)
-{
-	if (git_buf_is_allocated(out))
-		git_buf_free(out);
-
-	if (!size) {
-		git_buf_init(out, 0);
-	} else {
-		out->ptr   = (char *)ptr;
-		out->asize = 0;
-		out->size  = size;
-	}
-
-	return 0;
-}
-
 struct buf_stream {
 	git_writestream parent;
 	git_buf *target;
@@ -677,8 +660,10 @@ int git_filter_list_apply_to_data(
 	git_buf_sanitize(tgt);
 	git_buf_sanitize(src);
 
-	if (!filters)
-		return filter_list_out_buffer_from_raw(tgt, src->ptr, src->size);
+	if (!filters) {
+		git_buf_attach_notowned(tgt, src->ptr, src->size);
+		return 0;
+	}
 
 	buf_stream_init(&writer, tgt);
 
@@ -718,10 +703,7 @@ static int buf_from_blob(git_buf *out, git_blob *blob)
 		return -1;
 	}
 
-	out->ptr = (char *)git_blob_rawcontent(blob);
-	out->asize = 0;
-	out->size  = (size_t)rawsize;
-
+	git_buf_attach_notowned(out, git_blob_rawcontent(blob), (size_t)rawsize);
 	return 0;
 }