diff options
| -rw-r--r-- | pkt-line.c | 84 | ||||
| -rw-r--r-- | pkt-line.h | 4 | 
2 files changed, 76 insertions, 12 deletions
| diff --git a/pkt-line.c b/pkt-line.c index b691abebd7..bd603f8721 100644 --- a/pkt-line.c +++ b/pkt-line.c @@ -42,17 +42,19 @@ void packet_flush(int fd)  	safe_write(fd, "0000", 4);  } +void packet_buf_flush(struct strbuf *buf) +{ +	strbuf_add(buf, "0000", 4); +} +  #define hex(a) (hexchar[(a) & 15]) -void packet_write(int fd, const char *fmt, ...) +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]; - -	safe_read(fd, linelen, 4); +	int len = 0; -	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; +} diff --git a/pkt-line.h b/pkt-line.h index 9df653f6f5..1e5dcfe87c 100644 --- a/pkt-line.h +++ b/pkt-line.h @@ -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 | 
