pkt-line: parse other-ref lines Add support for parsing other-ref lines. Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
diff --git a/include/git2.h b/include/git2.h
index f94b535..b5c693a 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 4a0767e..680dcc6 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 94f42db..ef80435 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 782b885..a7562c4 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;
}