pkt-line: Add strbuf based functions
These routines help to work with pkt-line values inside of a strbuf, permitting simple formatting of buffered network messages. Signed-off-by: Shawn O. Pearce <spearce@spearce.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
							parent
							
								
									609621a4ad
								
							
						
					
					
						commit
						f5615d2467
					
				
							
								
								
									
										86
									
								
								pkt-line.c
								
								
								
								
							
							
						
						
									
										86
									
								
								pkt-line.c
								
								
								
								
							|  | @ -42,17 +42,19 @@ void packet_flush(int fd) | |||
| 	safe_write(fd, "0000", 4); | ||||
| } | ||||
|  | ||||
| #define hex(a) (hexchar[(a) & 15]) | ||||
| void packet_write(int fd, const char *fmt, ...) | ||||
| void packet_buf_flush(struct strbuf *buf) | ||||
| { | ||||
| 	strbuf_add(buf, "0000", 4); | ||||
| } | ||||
|  | ||||
| #define hex(a) (hexchar[(a) & 15]) | ||||
| static char buffer[1000]; | ||||
| static unsigned format_packet(const char *fmt, va_list args) | ||||
| { | ||||
| 	static char buffer[1000]; | ||||
| 	static char hexchar[] = "0123456789abcdef"; | ||||
| 	va_list args; | ||||
| 	unsigned n; | ||||
|  | ||||
| 	va_start(args, fmt); | ||||
| 	n = vsnprintf(buffer + 4, sizeof(buffer) - 4, fmt, args); | ||||
| 	va_end(args); | ||||
| 	if (n >= sizeof(buffer)-4) | ||||
| 		die("protocol error: impossibly long line"); | ||||
| 	n += 4; | ||||
|  | @ -60,9 +62,31 @@ void packet_write(int fd, const char *fmt, ...) | |||
| 	buffer[1] = hex(n >> 8); | ||||
| 	buffer[2] = hex(n >> 4); | ||||
| 	buffer[3] = hex(n); | ||||
| 	return n; | ||||
| } | ||||
|  | ||||
| void packet_write(int fd, const char *fmt, ...) | ||||
| { | ||||
| 	va_list args; | ||||
| 	unsigned n; | ||||
|  | ||||
| 	va_start(args, fmt); | ||||
| 	n = format_packet(fmt, args); | ||||
| 	va_end(args); | ||||
| 	safe_write(fd, buffer, n); | ||||
| } | ||||
|  | ||||
| void packet_buf_write(struct strbuf *buf, const char *fmt, ...) | ||||
| { | ||||
| 	va_list args; | ||||
| 	unsigned n; | ||||
|  | ||||
| 	va_start(args, fmt); | ||||
| 	n = format_packet(fmt, args); | ||||
| 	va_end(args); | ||||
| 	strbuf_add(buf, buffer, n); | ||||
| } | ||||
|  | ||||
| static void safe_read(int fd, void *buffer, unsigned size) | ||||
| { | ||||
| 	ssize_t ret = read_in_full(fd, buffer, size); | ||||
|  | @ -72,15 +96,11 @@ static void safe_read(int fd, void *buffer, unsigned size) | |||
| 		die("The remote end hung up unexpectedly"); | ||||
| } | ||||
|  | ||||
| int packet_read_line(int fd, char *buffer, unsigned size) | ||||
| static int packet_length(const char *linelen) | ||||
| { | ||||
| 	int n; | ||||
| 	unsigned len; | ||||
| 	char linelen[4]; | ||||
| 	int len = 0; | ||||
|  | ||||
| 	safe_read(fd, linelen, 4); | ||||
|  | ||||
| 	len = 0; | ||||
| 	for (n = 0; n < 4; n++) { | ||||
| 		unsigned char c = linelen[n]; | ||||
| 		len <<= 4; | ||||
|  | @ -96,8 +116,20 @@ int packet_read_line(int fd, char *buffer, unsigned size) | |||
| 			len += c - 'A' + 10; | ||||
| 			continue; | ||||
| 		} | ||||
| 		die("protocol error: bad line length character"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	return len; | ||||
| } | ||||
|  | ||||
| int packet_read_line(int fd, char *buffer, unsigned size) | ||||
| { | ||||
| 	int len; | ||||
| 	char linelen[4]; | ||||
|  | ||||
| 	safe_read(fd, linelen, 4); | ||||
| 	len = packet_length(linelen); | ||||
| 	if (len < 0) | ||||
| 		die("protocol error: bad line length character"); | ||||
| 	if (!len) | ||||
| 		return 0; | ||||
| 	len -= 4; | ||||
|  | @ -107,3 +139,31 @@ int packet_read_line(int fd, char *buffer, unsigned size) | |||
| 	buffer[len] = 0; | ||||
| 	return len; | ||||
| } | ||||
|  | ||||
| int packet_get_line(struct strbuf *out, | ||||
| 	char **src_buf, size_t *src_len) | ||||
| { | ||||
| 	int len; | ||||
|  | ||||
| 	if (*src_len < 4) | ||||
| 		return -1; | ||||
| 	len = packet_length(*src_buf); | ||||
| 	if (len < 0) | ||||
| 		return -1; | ||||
| 	if (!len) { | ||||
| 		*src_buf += 4; | ||||
| 		*src_len -= 4; | ||||
| 		return 0; | ||||
| 	} | ||||
| 	if (*src_len < len) | ||||
| 		return -2; | ||||
|  | ||||
| 	*src_buf += 4; | ||||
| 	*src_len -= 4; | ||||
| 	len -= 4; | ||||
|  | ||||
| 	strbuf_add(out, *src_buf, len); | ||||
| 	*src_buf += len; | ||||
| 	*src_len -= len; | ||||
| 	return len; | ||||
| } | ||||
|  |  | |||
|  | @ -2,14 +2,18 @@ | |||
| #define PKTLINE_H | ||||
|  | ||||
| #include "git-compat-util.h" | ||||
| #include "strbuf.h" | ||||
|  | ||||
| /* | ||||
|  * Silly packetized line writing interface | ||||
|  */ | ||||
| void packet_flush(int fd); | ||||
| void packet_write(int fd, const char *fmt, ...) __attribute__((format (printf, 2, 3))); | ||||
| void packet_buf_flush(struct strbuf *buf); | ||||
| void packet_buf_write(struct strbuf *buf, const char *fmt, ...) __attribute__((format (printf, 2, 3))); | ||||
|  | ||||
| int packet_read_line(int fd, char *buffer, unsigned size); | ||||
| int packet_get_line(struct strbuf *out, char **src_buf, size_t *src_len); | ||||
| ssize_t safe_write(int, const void *, ssize_t); | ||||
|  | ||||
| #endif | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Shawn O. Pearce
						Shawn O. Pearce