pkt-line: add functions to read/write flush terminated packet streams
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>maint
							parent
							
								
									edfb780cd4
								
							
						
					
					
						commit
						bb643d8bf8
					
				
							
								
								
									
										72
									
								
								pkt-line.c
								
								
								
								
							
							
						
						
									
										72
									
								
								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) | ||||
| { | ||||
|  | @ -287,3 +327,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; | ||||
| } | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Lars Schneider
						Lars Schneider