git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 09/12] vcs-svn: add binary-safe read function

From
Jonathan Nieder <jrnieder@gmail.com>
Date
Jan 3, 2011, 03:05 UTC
Message-ID
<20110103030546.GB10143@burratino>
In-Reply-To
<20110103030328.GA10143@burratino>

buffer_read_string works well for non line-oriented input except for one problem: it does not tell the caller how many bytes were actually written. This means that unless one is very careful about checking for errors (and eof) the calling program cannot tell the difference between the string "foo" followed by an early end of file and the string "foo\0bar\0baz".

So introduce a variant that reports the length, too, a thinner wrapper around strbuf_fread. Its result is written to a strbuf so the caller does not need to keep track of the number of bytes read.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 t/t0081-line-buffer.sh |   18 ++++++++++++++++++
 test-line-buffer.c     |   10 ++++++++++
 vcs-svn/line_buffer.c  |    6 ++++++
 vcs-svn/line_buffer.h  |    1 +
 4 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/t/t0081-line-buffer.sh b/t/t0081-line-buffer.sh
index 33a728e..a8eeb20 100755
--- a/t/t0081-line-buffer.sh
+++ b/t/t0081-line-buffer.sh
@@ -151,6 +151,15 @@ test_expect_success 'skip, copy null byte' '
 	test_cmp expect actual
 '
 
+test_expect_success 'read null byte' '
+	echo ">QhelloQ" | q_to_nul >expect &&
+	q_to_nul <<-\EOF | test-line-buffer >actual &&
+	binary 8
+	QhelloQ
+	EOF
+	test_cmp expect actual
+'
+
 test_expect_success 'long reads are truncated' '
 	echo foo >expect &&
 	test-line-buffer <<-\EOF >actual &&
@@ -171,4 +180,13 @@ test_expect_success 'long copies are truncated' '
 	test_cmp expect actual
 '
 
+test_expect_success 'long binary reads are truncated' '
+	echo ">foo" >expect &&
+	test-line-buffer <<-\EOF >actual &&
+	binary 5
+	foo
+	EOF
+	test_cmp expect actual
+'
+
 test_done
diff --git a/test-line-buffer.c b/test-line-buffer.c
index ec19b13..19bf2d4 100644
--- a/test-line-buffer.c
+++ b/test-line-buffer.c
@@ -3,6 +3,7 @@
  */
 
 #include "git-compat-util.h"
+#include "strbuf.h"
 #include "vcs-svn/line_buffer.h"
 
 static uint32_t strtouint32(const char *s)
@@ -17,6 +18,15 @@ static uint32_t strtouint32(const char *s)
 static void handle_command(const char *command, const char *arg, struct line_buffer *buf)
 {
 	switch (*command) {
+	case 'b':
+		if (!prefixcmp(command, "binary ")) {
+			struct strbuf sb = STRBUF_INIT;
+			strbuf_addch(&sb, '>');
+			buffer_read_binary(buf, &sb, strtouint32(arg));
+			fwrite(sb.buf, 1, sb.len, stdout);
+			strbuf_release(&sb);
+			return;
+		}
 	case 'c':
 		if (!prefixcmp(command, "copy ")) {
 			buffer_copy_bytes(buf, strtouint32(arg));
diff --git a/vcs-svn/line_buffer.c b/vcs-svn/line_buffer.c
index 806932b..661b007 100644
--- a/vcs-svn/line_buffer.c
+++ b/vcs-svn/line_buffer.c
@@ -56,6 +56,12 @@ char *buffer_read_string(struct line_buffer *buf, uint32_t len)
 	return ferror(buf->infile) ? NULL : buf->blob_buffer.buf;
 }
 
+void buffer_read_binary(struct line_buffer *buf,
+				struct strbuf *sb, uint32_t size)
+{
+	strbuf_fread(sb, size, buf->infile);
+}
+
 void buffer_copy_bytes(struct line_buffer *buf, uint32_t len)
 {
 	char byte_buffer[COPY_BUFFER_LEN];
diff --git a/vcs-svn/line_buffer.h b/vcs-svn/line_buffer.h
index fb37390..0c2d3d9 100644
--- a/vcs-svn/line_buffer.h
+++ b/vcs-svn/line_buffer.h
@@ -16,6 +16,7 @@ int buffer_init(struct line_buffer *buf, const char *filename);
 int buffer_deinit(struct line_buffer *buf);
 char *buffer_read_line(struct line_buffer *buf);
 char *buffer_read_string(struct line_buffer *buf, uint32_t len);
+void buffer_read_binary(struct line_buffer *buf, struct strbuf *sb, uint32_t len);
 void buffer_copy_bytes(struct line_buffer *buf, uint32_t len);
 void buffer_skip_bytes(struct line_buffer *buf, uint32_t len);
 void buffer_reset(struct line_buffer *buf);
-- 
1.7.4.rc0.580.g89dc.dirty
Previous: Jonathan NiederNext: Jonathan Nieder
Message 13 of 25 in “teach vcs-svn/line_buffer to handle multiple input files”
  1. 0/4 teach vcs-svn/line_buffer to handle multiple input filesJonathan Nieder, Dec 24, 2010
  2. 1/4 vcs-svn: eliminate global byte_bufferJonathan Nieder, Dec 24, 2010
  3. 2/4 vcs-svn: replace buffer_read_string memory pool with a strbufJonathan Nieder, Dec 24, 2010
  4. 3/4 vcs-svn: collect line_buffer data in a structJonathan Nieder, Dec 24, 2010
  5. 4/4 vcs-svn: teach line_buffer to handle multiple input filesJonathan Nieder, Dec 24, 2010
  6. Jonathan NiederJan 3, 2011
  7. 5/8 vcs-svn: make test-line-buffer input format more flexibleJonathan Nieder, Jan 3, 2011
  8. 6/8 tests: give vcs-svn/line_buffer its own test scriptJonathan Nieder, Jan 3, 2011
  9. 7/8 vcs-svn: tweak test-line-buffer to not assume line-oriented inputJonathan Nieder, Jan 3, 2011
  10. 8/8 t0081 (line-buffer): add buffering testsJonathan Nieder, Jan 3, 2011
  11. Jonathan NiederJan 3, 2011
  12. 12/12 line_buffer: more wrappers around stdio functionsJonathan Nieder, Jan 3, 2011
  13. 09/12 vcs-svn: add binary-safe read functionJonathan Nieder, Jan 3, 2011
  14. 10/12 vcs-svn: allow character-oriented inputJonathan Nieder, Jan 3, 2011
  15. 11/12 vcs-svn: allow input from file descriptorJonathan Nieder, Jan 3, 2011
  16. 12/12 vcs-svn: teach line_buffer about temporary filesJonathan Nieder, Jan 3, 2011
  17. vcs-svn: give control over temporary file namesJonathan Nieder, Jan 22, 2011
  18. [PULL svn-fe] fast-import 'ls', line-buffer changesJonathan Nieder, Feb 26, 2011
  19. David Michael BarrFeb 26, 2011
  20. Junio C HamanoFeb 28, 2011
  21. fast-import: make code "-Wpointer-arith" cleanJonathan Nieder, Feb 28, 2011
  22. Sverre RabbelierFeb 28, 2011
  23. Junio C HamanoFeb 28, 2011
  24. Jonathan NiederFeb 28, 2011
  25. Junio C HamanoMar 1, 2011

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.