summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <carlos@cmartin.tk>2011-05-28 11:59:10 +0200
committerCarlos Martín Nieto <carlos@cmartin.tk>2011-06-26 18:18:12 +0200
commitb31803f3106f657a6cc6b8c4fd69e017edad2af8 (patch)
tree3b31c735496054ef1dfdf77e6926da1c675145f8
parent78fae47878111dd9833345fa622bafb51e5d69b5 (diff)
downloadlibgit2-b31803f3106f657a6cc6b8c4fd69e017edad2af8.tar.gz
pkt-line: parse other-ref lines
Add support for parsing other-ref lines. Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
-rw-r--r--include/git2.h1
-rw-r--r--include/git2/pkt.h4
-rw-r--r--include/git2/types.h2
-rw-r--r--src/pkt.c61
4 files changed, 61 insertions, 7 deletions
diff --git a/include/git2.h b/include/git2.h
index f94b535c4..b5c693a82 100644
--- a/include/git2.h
+++ b/include/git2.h
@@ -60,5 +60,6 @@
#include "git2/net.h"
#include "git2/transport.h"
+#include "git2/pkt.h"
#endif
diff --git a/include/git2/pkt.h b/include/git2/pkt.h
index 4a0767e27..680dcc618 100644
--- a/include/git2/pkt.h
+++ b/include/git2/pkt.h
@@ -28,7 +28,7 @@
enum git_pkt_type {
GIT_PKT_CMD,
GIT_PKT_FLUSH,
- GIT_PKT_HEAD,
+ GIT_PKT_REF,
GIT_PKT_HAVE,
};
@@ -45,7 +45,7 @@ struct git_pkt_cmd {
};
/* This is a pkt-line with some info in it */
-struct git_pkt_head {
+struct git_pkt_ref {
enum git_pkt_type type;
git_remote_head head;
};
diff --git a/include/git2/types.h b/include/git2/types.h
index 94f42db62..ef80435c4 100644
--- a/include/git2/types.h
+++ b/include/git2/types.h
@@ -186,7 +186,7 @@ typedef struct git_headarray git_headarray;
typedef enum git_pkt_type git_pkt_type;
typedef struct git_pkt git_pkt;
typedef struct git_pkt_cmd git_pkt_cmd;
-typedef struct git_pkt_head git_pkt_head;
+typedef struct git_pkt_ref git_pkt_ref;
/** @} */
GIT_END_DECL
diff --git a/src/pkt.c b/src/pkt.c
index 782b88569..a7562c455 100644
--- a/src/pkt.c
+++ b/src/pkt.c
@@ -45,6 +45,53 @@ static int flush_pkt(git_pkt **out)
}
/*
+ * Parse an other-ref line.
+ */
+int ref_pkt(git_pkt **out, const char *line, size_t len)
+{
+ git_pkt_ref *pkt;
+ int error;
+ size_t name_len;
+
+ pkt = git__malloc(sizeof(git_pkt_ref));
+ if (pkt == NULL)
+ return GIT_ENOMEM;
+
+ pkt->type = GIT_PKT_REF;
+ error = git_oid_fromstr(&pkt->head.oid, line);
+ if (error < GIT_SUCCESS) {
+ error = git__throw(error, "Failed to parse reference ID");
+ goto out;
+ }
+
+ /* Check for a bit of consistency */
+ if (line[GIT_OID_HEXSZ] != ' ') {
+ error = git__throw(GIT_EOBJCORRUPTED, "Failed to parse ref. No SP");
+ goto out;
+ }
+
+ line += GIT_OID_HEXSZ + 1;
+
+ name_len = len - (GIT_OID_HEXSZ + 1);
+ if (line[name_len - 1] == '\n')
+ --name_len;
+
+ pkt->head.name = git__strndup(line, name_len);
+ if (pkt->head.name == NULL) {
+ error = GIT_ENOMEM;
+ goto out;
+ }
+
+out:
+ if (error < GIT_SUCCESS)
+ free(pkt);
+ else
+ *out = (git_pkt *)pkt;
+
+ return error;
+}
+
+/*
* As per the documentation, the syntax is:
*
* pkt-line = data-pkt / flush-pkt
@@ -64,7 +111,6 @@ int git_pkt_parse_line(git_pkt **head, const char *line, const char **out)
const int num_len = 4;
char *num;
const char *num_end;
- git_pkt *pkt;
num = git__strndup(line, num_len);
if (num == NULL)
@@ -73,7 +119,7 @@ int git_pkt_parse_line(git_pkt **head, const char *line, const char **out)
error = git__strtol32(&len, num, &num_end, 16);
if (error < GIT_SUCCESS) {
free(num);
- return error;
+ return git__throw(error, "Failed to parse pkt length");
}
if (num_end - num != num_len) {
free(num);
@@ -96,7 +142,14 @@ int git_pkt_parse_line(git_pkt **head, const char *line, const char **out)
return flush_pkt(head);
}
- /* TODO: Write the rest of this thing */
+ len -= num_len; /* the length includes the space for the length */
- return GIT_SUCCESS;
+ /*
+ * For now, we're just going to assume we're parsing references
+ */
+
+ error = ref_pkt(head, line, len);
+ *out = line + len;
+
+ return error;
}