diff options
author | Chris Hescock <chescock@vistaprint.com> | 2016-03-08 10:16:37 -0500 |
---|---|---|
committer | Chris Hescock <chescock@vistaprint.com> | 2016-03-08 10:43:37 -0500 |
commit | 9028a8a22acd81b299140ea90bab5f8e99ccb01d (patch) | |
tree | dee8f0ac7589a058afc0aba031348dc2d3fe4623 | |
parent | a7d9d93dad9b0965575906f5bf344867eb5b2a0e (diff) | |
download | libgit2-9028a8a22acd81b299140ea90bab5f8e99ccb01d.tar.gz |
Only buffer if necessary.
-rw-r--r-- | src/transports/smart_protocol.c | 57 |
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", |