summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Hescock <chescock@vistaprint.com>2016-03-08 10:16:37 -0500
committerChris Hescock <chescock@vistaprint.com>2016-03-08 10:43:37 -0500
commit9028a8a22acd81b299140ea90bab5f8e99ccb01d (patch)
treedee8f0ac7589a058afc0aba031348dc2d3fe4623
parenta7d9d93dad9b0965575906f5bf344867eb5b2a0e (diff)
downloadlibgit2-9028a8a22acd81b299140ea90bab5f8e99ccb01d.tar.gz
Only buffer if necessary.
-rw-r--r--src/transports/smart_protocol.c57
1 files changed, 39 insertions, 18 deletions
diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c
index c8eb611d8..ee113920f 100644
--- a/src/transports/smart_protocol.c
+++ b/src/transports/smart_protocol.c
@@ -719,30 +719,58 @@ static int add_push_report_pkt(git_push *push, git_pkt *pkt)
return 0;
}
-static int add_push_report_sideband_pkt(git_push *push, git_buf *data_pkt_buf)
+static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt, git_buf *data_pkt_buf)
{
git_pkt *pkt;
- const char *line_end;
+ const char *line, *line_end;
+ size_t line_len;
int error;
+ int reading_from_buf = data_pkt_buf->size > 0;
+
+ if (reading_from_buf) {
+ /* We had an existing partial packet, so add the new
+ * packet to the buffer and parse the whole thing */
+ git_buf_put(data_pkt_buf, data_pkt->data, data_pkt->len);
+ line = data_pkt_buf->ptr;
+ line_len = data_pkt_buf->size;
+ }
+ else {
+ line = data_pkt->data;
+ line_len = data_pkt->len;
+ }
- while (data_pkt_buf->size > 0) {
- error = git_pkt_parse_line(&pkt, data_pkt_buf->ptr, &line_end, data_pkt_buf->size);
+ while (line_len > 0) {
+ error = git_pkt_parse_line(&pkt, line, &line_end, line_len);
- if (error < 0)
- return error;
+ if (error == GIT_EBUFS) {
+ /* Buffer the data when the inner packet is split
+ * across multiple sideband packets */
+ if (!reading_from_buf)
+ git_buf_put(data_pkt_buf, line, line_len);
+ error = 0;
+ goto done;
+ }
+ else if (error < 0)
+ goto done;
/* Advance in the buffer */
- git_buf_consume(data_pkt_buf, line_end);
+ line_len -= (line_end - line);
+ line = line_end;
error = add_push_report_pkt(push, pkt);
git_pkt_free(pkt);
if (error < 0 && error != GIT_ITEROVER)
- return error;
+ goto done;
}
- return 0;
+ error = 0;
+
+done:
+ if (reading_from_buf)
+ git_buf_consume(data_pkt_buf, line_end);
+ return error;
}
static int parse_report(transport_smart *transport, git_push *push)
@@ -752,7 +780,6 @@ static int parse_report(transport_smart *transport, git_push *push)
gitno_buffer *buf = &transport->buffer;
int error, recvd;
git_buf data_pkt_buf = GIT_BUF_INIT;
- git_pkt_data *data_pkt;
for (;;) {
if (buf->offset > 0)
@@ -786,14 +813,8 @@ static int parse_report(transport_smart *transport, git_push *push)
switch (pkt->type) {
case GIT_PKT_DATA:
- /* This is a sideband packet which contains other packets
- * Buffer the data in case the inner packet is split
- * across multiple sideband packets */
- data_pkt = (git_pkt_data *)pkt;
- git_buf_put(&data_pkt_buf, data_pkt->data, data_pkt->len);
- error = add_push_report_sideband_pkt(push, &data_pkt_buf);
- if (error == GIT_EBUFS)
- error = 0;
+ /* This is a sideband packet which contains other packets */
+ error = add_push_report_sideband_pkt(push, (git_pkt_data *)pkt, &data_pkt_buf);
break;
case GIT_PKT_ERR:
giterr_set(GITERR_NET, "report-status: Error reported: %s",