Commit 65c86048 by Carlos Martín Nieto Committed by Vicent Marti

Introduce the git_pkt_buffer_ family of functions

Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
parent f9613325
...@@ -262,6 +262,12 @@ void git_pkt_free(git_pkt *pkt) ...@@ -262,6 +262,12 @@ void git_pkt_free(git_pkt *pkt)
free(pkt); free(pkt);
} }
int git_pkt_buffer_flush(git_buf *buf)
{
git_buf_puts(buf, "0000");
return git_buf_oom(buf) ? GIT_ENOMEM : GIT_SUCCESS;
}
int git_pkt_send_flush(int s, int chunked) int git_pkt_send_flush(int s, int chunked)
{ {
char flush[] = "0000"; char flush[] = "0000";
...@@ -275,30 +281,36 @@ int git_pkt_send_flush(int s, int chunked) ...@@ -275,30 +281,36 @@ int git_pkt_send_flush(int s, int chunked)
return gitno_send(s, flush, strlen(flush), 0); return gitno_send(s, flush, strlen(flush), 0);
} }
static int send_want_with_caps(git_remote_head *head, git_transport_caps *caps, int fd, int chunked) static int buffer_want_with_caps(git_remote_head *head, git_transport_caps *caps, git_buf *buf)
{ {
char capstr[20]; /* Longer than we need */ char capstr[20];
char oid[GIT_OID_HEXSZ +1] = {0}, *cmd; char oid[GIT_OID_HEXSZ +1] = {0};
int error, len; int len;
git_buf buf = GIT_BUF_INIT;
if (caps->ofs_delta) if (caps->ofs_delta)
strcpy(capstr, GIT_CAP_OFS_DELTA); strcpy(capstr, GIT_CAP_OFS_DELTA);
len = strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ + strlen(capstr) + 1 /* LF */; len = strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ + strlen(capstr) + 1 /* LF */;
cmd = git__malloc(len + 1); git_buf_grow(buf, buf->size + len);
if (cmd == NULL)
return GIT_ENOMEM;
git_oid_fmt(oid, &head->oid); git_oid_fmt(oid, &head->oid);
git_buf_printf(&buf, "%04xwant %s%c%s\n", len, oid, 0, capstr); git_buf_printf(buf, "%04xwant %s%c%s\n", len, oid, 0, capstr);
if (chunked) {
error = gitno_send_chunk_size(fd, len); return git_buf_oom(buf) ? GIT_ENOMEM : GIT_SUCCESS;
}
static int send_want_with_caps(git_remote_head *head, git_transport_caps *caps, GIT_SOCKET fd)
{
git_buf buf = GIT_BUF_INIT;
int error;
error = buffer_want_with_caps(head, caps, &buf);
if (error < GIT_SUCCESS) if (error < GIT_SUCCESS)
return git__rethrow(error, "Failed to send first want chunk size"); return git__rethrow(error, "Failed to buffer want with caps");
}
error = gitno_send(fd, git_buf_cstr(&buf), len, 0); error = gitno_send(fd, buf.ptr, buf.size, 0);
free(cmd); git_buf_free(&buf);
return error; return error;
} }
...@@ -308,6 +320,41 @@ static int send_want_with_caps(git_remote_head *head, git_transport_caps *caps, ...@@ -308,6 +320,41 @@ static int send_want_with_caps(git_remote_head *head, git_transport_caps *caps,
*/ */
#define WANT_PREFIX "0032want " #define WANT_PREFIX "0032want "
int git_pkt_buffer_wants(git_headarray *refs, git_transport_caps *caps, git_buf *buf)
{
unsigned int i = 0;
int error;
git_remote_head *head;
if (caps->common) {
for (; i < refs->len; ++i) {
head = refs->heads[i];
if (!head->local)
break;
}
error = buffer_want_with_caps(refs->heads[i], caps, buf);
if (error < GIT_SUCCESS)
return git__rethrow(error, "Failed to buffer want with caps");
i++;
}
for (; i < refs->len; ++i) {
char oid[GIT_OID_HEXSZ];
head = refs->heads[i];
if (head->local)
continue;
git_oid_fmt(oid, &head->oid);
git_buf_puts(buf, WANT_PREFIX);
git_buf_put(buf, oid, GIT_OID_HEXSZ);
}
return git_pkt_buffer_flush(buf);
}
int git_pkt_send_wants(git_headarray *refs, git_transport_caps *caps, int fd, int chunked) int git_pkt_send_wants(git_headarray *refs, git_transport_caps *caps, int fd, int chunked)
{ {
unsigned int i = 0; unsigned int i = 0;
...@@ -329,7 +376,7 @@ int git_pkt_send_wants(git_headarray *refs, git_transport_caps *caps, int fd, in ...@@ -329,7 +376,7 @@ int git_pkt_send_wants(git_headarray *refs, git_transport_caps *caps, int fd, in
break; break;
} }
error = send_want_with_caps(refs->heads[i], caps, fd, chunked); error = send_want_with_caps(refs->heads[i], caps, fd);
if (error < GIT_SUCCESS) if (error < GIT_SUCCESS)
return git__rethrow(error, "Failed to send want pkt with caps"); return git__rethrow(error, "Failed to send want pkt with caps");
/* Increase it here so it's correct whether we run this or not */ /* Increase it here so it's correct whether we run this or not */
...@@ -356,12 +403,18 @@ int git_pkt_send_wants(git_headarray *refs, git_transport_caps *caps, int fd, in ...@@ -356,12 +403,18 @@ int git_pkt_send_wants(git_headarray *refs, git_transport_caps *caps, int fd, in
return git_pkt_send_flush(fd, chunked); return git_pkt_send_flush(fd, chunked);
} }
/*
* TODO: this should be a more generic function, maybe to be used by
* git_pkt_send_wants, as it's not performance-critical
*/
#define HAVE_PREFIX "0032have " #define HAVE_PREFIX "0032have "
int git_pkt_buffer_have(git_oid *oid, git_buf *buf)
{
char oidhex[GIT_OID_HEXSZ + 1];
memset(oidhex, 0x0, sizeof(oidhex));
git_oid_fmt(oidhex, oid);
git_buf_printf(buf, "%s%s\n", HAVE_PREFIX, oidhex);
return git_buf_oom(buf) ? GIT_ENOMEM : GIT_SUCCESS;
}
int git_pkt_send_have(git_oid *oid, int fd, int chunked) int git_pkt_send_have(git_oid *oid, int fd, int chunked)
{ {
char buf[] = "0032have 0000000000000000000000000000000000000000\n"; char buf[] = "0032have 0000000000000000000000000000000000000000\n";
...@@ -376,6 +429,14 @@ int git_pkt_send_have(git_oid *oid, int fd, int chunked) ...@@ -376,6 +429,14 @@ int git_pkt_send_have(git_oid *oid, int fd, int chunked)
return gitno_send(fd, buf, strlen(buf), 0); return gitno_send(fd, buf, strlen(buf), 0);
} }
static char *donestr = "0009done\n";
int git_pkt_buffer_done(git_buf *buf)
{
git_buf_puts(buf, donestr);
return git_buf_oom(buf) ? GIT_ENOMEM : GIT_SUCCESS;
}
int git_pkt_send_done(int fd, int chunked) int git_pkt_send_done(int fd, int chunked)
{ {
char buf[] = "0009done\n"; char buf[] = "0009done\n";
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "common.h" #include "common.h"
#include "transport.h" #include "transport.h"
#include "buffer.h"
#include "git2/net.h" #include "git2/net.h"
enum git_pkt_type { enum git_pkt_type {
...@@ -63,9 +64,13 @@ typedef struct { ...@@ -63,9 +64,13 @@ typedef struct {
} git_pkt_comment; } git_pkt_comment;
int git_pkt_parse_line(git_pkt **head, const char *line, const char **out, size_t len); int git_pkt_parse_line(git_pkt **head, const char *line, const char **out, size_t len);
int git_pkt_buffer_flush(git_buf *buf);
int git_pkt_send_flush(int s, int chunked); int git_pkt_send_flush(int s, int chunked);
int git_pkt_buffer_done(git_buf *buf);
int git_pkt_send_done(int s, int chunked); int git_pkt_send_done(int s, int chunked);
int git_pkt_buffer_wants(git_headarray *refs, git_transport_caps *caps, git_buf *buf);
int git_pkt_send_wants(git_headarray *refs, git_transport_caps *caps, int fd, int chunked); int git_pkt_send_wants(git_headarray *refs, git_transport_caps *caps, int fd, int chunked);
int git_pkt_buffer_have(git_oid *oid, git_buf *buf);
int git_pkt_send_have(git_oid *oid, int fd, int chunked); int git_pkt_send_have(git_oid *oid, int fd, int chunked);
void git_pkt_free(git_pkt *pkt); void git_pkt_free(git_pkt *pkt);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment