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

[PATCH v10 10/14] pkt-line: add functions to read/write flush terminated packet streams

From
larsxschneider@gmail.com <larsxschneider@gmail.com>
Date
Oct 8, 2016, 11:25 UTC
Message-ID
<20161008112530.15506-11-larsxschneider@gmail.com>
In-Reply-To
<20161008112530.15506-1-larsxschneider@gmail.com>
From: Lars Schneider <larsxschneider@gmail.com>

write_packetized_from_fd() and write_packetized_from_buf() write a stream of packets. All content packets use the maximal packet size except for the last one. After the last content packet a `flush` control packet is written.

read_packetized_to_strbuf() reads arbitrary sized packets until it detects a `flush` packet.

Signed-off-by: Lars Schneider <larsxschneider@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 pkt-line.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 pkt-line.h |  8 +++++++
 2 files changed, 80 insertions(+)
diff --git a/pkt-line.c b/pkt-line.c
index dca5a64..0b5125f 100644
--- a/pkt-line.c
+++ b/pkt-line.c
@@ -197,6 +197,46 @@ void packet_buf_write(struct strbuf *buf, const char *fmt, ...)
 	va_end(args);
 }
 
+int write_packetized_from_fd(int fd_in, int fd_out)
+{
+	static char buf[LARGE_PACKET_DATA_MAX];
+	int err = 0;
+	ssize_t bytes_to_write;
+
+	while (!err) {
+		bytes_to_write = xread(fd_in, buf, sizeof(buf));
+		if (bytes_to_write < 0)
+			return COPY_READ_ERROR;
+		if (bytes_to_write == 0)
+			break;
+		err = packet_write_gently(fd_out, buf, bytes_to_write);
+	}
+	if (!err)
+		err = packet_flush_gently(fd_out);
+	return err;
+}
+
+int write_packetized_from_buf(const char *src_in, size_t len, int fd_out)
+{
+	int err = 0;
+	size_t bytes_written = 0;
+	size_t bytes_to_write;
+
+	while (!err) {
+		if ((len - bytes_written) > LARGE_PACKET_DATA_MAX)
+			bytes_to_write = LARGE_PACKET_DATA_MAX;
+		else
+			bytes_to_write = len - bytes_written;
+		if (bytes_to_write == 0)
+			break;
+		err = packet_write_gently(fd_out, src_in + bytes_written, bytes_to_write);
+		bytes_written += bytes_to_write;
+	}
+	if (!err)
+		err = packet_flush_gently(fd_out);
+	return err;
+}
+
 static int get_packet_data(int fd, char **src_buf, size_t *src_size,
 			   void *dst, unsigned size, int options)
 {
@@ -306,3 +346,35 @@ char *packet_read_line_buf(char **src, size_t *src_len, int *dst_len)
 {
 	return packet_read_line_generic(-1, src, src_len, dst_len);
 }
+
+ssize_t read_packetized_to_strbuf(int fd_in, struct strbuf *sb_out)
+{
+	int packet_len;
+
+	size_t orig_len = sb_out->len;
+	size_t orig_alloc = sb_out->alloc;
+
+	for (;;) {
+		strbuf_grow(sb_out, LARGE_PACKET_DATA_MAX);
+		packet_len = packet_read(fd_in, NULL, NULL,
+			/* strbuf_grow() above always allocates one extra byte to
+			 * store a '\0' at the end of the string. packet_read()
+			 * writes a '\0' extra byte at the end, too. Let it know
+			 * that there is already room for the extra byte.
+			 */
+			sb_out->buf + sb_out->len, LARGE_PACKET_DATA_MAX+1,
+			PACKET_READ_GENTLE_ON_EOF);
+		if (packet_len <= 0)
+			break;
+		sb_out->len += packet_len;
+	}
+
+	if (packet_len < 0) {
+		if (orig_alloc == 0)
+			strbuf_release(sb_out);
+		else
+			strbuf_setlen(sb_out, orig_len);
+		return packet_len;
+	}
+	return sb_out->len - orig_len;
+}
diff --git a/pkt-line.h b/pkt-line.h
index 3fa0899..18eac64 100644
--- a/pkt-line.h
+++ b/pkt-line.h
@@ -25,6 +25,8 @@ void packet_buf_flush(struct strbuf *buf);
 void packet_buf_write(struct strbuf *buf, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
 int packet_flush_gently(int fd);
 int packet_write_fmt_gently(int fd, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
+int write_packetized_from_fd(int fd_in, int fd_out);
+int write_packetized_from_buf(const char *src_in, size_t len, int fd_out);
 
 /*
  * Read a packetized line into the buffer, which must be at least size bytes
@@ -77,8 +79,14 @@ char *packet_read_line(int fd, int *size);
  */
 char *packet_read_line_buf(char **src_buf, size_t *src_len, int *size);
 
+/*
+ * Reads a stream of variable sized packets until a flush packet is detected.
+ */
+ssize_t read_packetized_to_strbuf(int fd_in, struct strbuf *sb_out);
+
 #define DEFAULT_PACKET_MAX 1000
 #define LARGE_PACKET_MAX 65520
+#define LARGE_PACKET_DATA_MAX (LARGE_PACKET_MAX - 4)
 extern char packet_buffer[LARGE_PACKET_MAX];
 
 #endif
-- 
2.10.0
Previous: Junio C HamanoNext: larsxschneider@gmail.com
Message 31 of 34 in “Git filter protocol”
  1. 00/14 Git filter protocollarsxschneider@gmail.com, Oct 8, 2016
  2. 01/14 convert: quote filter names in error messageslarsxschneider@gmail.com, Oct 8, 2016
  3. 02/14 convert: modernize testslarsxschneider@gmail.com, Oct 8, 2016
  4. 03/14 run-command: move check_pipe() from write_or_die to run_commandlarsxschneider@gmail.com, Oct 8, 2016
  5. 04/14 run-command: add clean_on_exit_handlerlarsxschneider@gmail.com, Oct 8, 2016
  6. Johannes SchindelinOct 11, 2016
  7. Lars SchneiderOct 15, 2016
  8. Johannes SchindelinOct 16, 2016
  9. Lars SchneiderOct 16, 2016
  10. 05/14 pkt-line: rename packet_write() to packet_write_fmt()larsxschneider@gmail.com, Oct 8, 2016
  11. 07/14 pkt-line: add packet_write_fmt_gently()larsxschneider@gmail.com, Oct 8, 2016
  12. 08/14 pkt-line: add packet_flush_gently()larsxschneider@gmail.com, Oct 8, 2016
  13. 09/14 pkt-line: add packet_write_gently()larsxschneider@gmail.com, Oct 8, 2016
  14. 11/14 convert: make apply_filter() adhere to standard Git error handlinglarsxschneider@gmail.com, Oct 8, 2016
  15. 06/14 pkt-line: extract set_packet_header()larsxschneider@gmail.com, Oct 8, 2016
  16. 12/14 convert: prepare filter.<driver>.process optionlarsxschneider@gmail.com, Oct 8, 2016
  17. 13/14 convert: add filter.<driver>.process optionlarsxschneider@gmail.com, Oct 8, 2016
  18. Jakub NarębskiOct 8, 2016
  19. Torsten BögershausenOct 9, 2016
  20. Lars SchneiderOct 11, 2016
  21. Lars SchneiderOct 11, 2016
  22. Jakub NarębskiOct 12, 2016
  23. Lars SchneiderOct 15, 2016
  24. Jeff KingOct 15, 2016
  25. Jakub NarębskiOct 15, 2016
  26. Junio C HamanoOct 10, 2016
  27. Lars SchneiderOct 11, 2016
  28. Torsten BögershausenOct 11, 2016
  29. Lars SchneiderOct 16, 2016
  30. Junio C HamanoOct 17, 2016
  31. 10/14 pkt-line: add functions to read/write flush terminated packet streamslarsxschneider@gmail.com, Oct 8, 2016
  32. 14/14 contrib/long-running-filter: add long running filter examplelarsxschneider@gmail.com, Oct 8, 2016
  33. Torsten BögershausenOct 9, 2016
  34. Lars SchneiderOct 15, 2016

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.