[PATCH 28/38] pack v4: code to load and prepare a pack dictionary table for use

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Nicolas Pitre <nico@xxxxxxxxxxx>
---
 packv4-parse.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)

diff --git a/packv4-parse.c b/packv4-parse.c
index 299fc48..26894bc 100644
--- a/packv4-parse.c
+++ b/packv4-parse.c
@@ -28,3 +28,80 @@ const unsigned char *get_sha1ref(struct packed_git *p,
 
 	return sha1;
 }
+
+struct packv4_dict {
+	const unsigned char *data;
+	unsigned int nb_entries;
+	unsigned int offsets[FLEX_ARRAY];
+};
+
+static struct packv4_dict *load_dict(struct packed_git *p, off_t *offset)
+{
+	struct pack_window *w_curs = NULL;
+	off_t curpos = *offset;
+	unsigned long dict_size, avail;
+	unsigned char *src, *data;
+	const unsigned char *cp;
+	git_zstream stream;
+	struct packv4_dict *dict;
+	int nb_entries, i, st;
+
+	/* get uncompressed dictionary data size */
+	src = use_pack(p, &w_curs, curpos, &avail);
+	cp = src;
+	dict_size = decode_varint(&cp);
+	if (dict_size < 3) {
+		error("bad dict size");
+		return NULL;
+	}
+	curpos += cp - src;
+
+	data = xmallocz(dict_size);
+	memset(&stream, 0, sizeof(stream));
+	stream.next_out = data;
+	stream.avail_out = dict_size + 1;
+
+	git_inflate_init(&stream);
+	do {
+		src = use_pack(p, &w_curs, curpos, &stream.avail_in);
+		stream.next_in = src;
+		st = git_inflate(&stream, Z_FINISH);
+		curpos += stream.next_in - src;
+	} while ((st == Z_OK || st == Z_BUF_ERROR) && stream.avail_out);
+	git_inflate_end(&stream);
+	unuse_pack(&w_curs);
+	if (st != Z_STREAM_END || stream.total_out != dict_size) {
+		error("pack dictionary bad");
+		free(data);
+		return NULL;
+	}
+
+	/* count number of entries */
+	nb_entries = 0;
+	cp = data;
+	while (cp < data + dict_size - 3) {
+		cp += 2;  /* prefix bytes */
+		cp += strlen((const char *)cp);  /* entry string */
+		cp += 1;  /* terminating NUL */
+		nb_entries++;
+	}
+	if (cp - data != dict_size) {
+		error("dict size mismatch");
+		free(data);
+		return NULL;
+	}
+
+	dict = xmalloc(sizeof(*dict) + nb_entries * sizeof(dict->offsets[0]));
+	dict->data = data;
+	dict->nb_entries = nb_entries;
+
+	cp = data;
+	for (i = 0; i < nb_entries; i++) {
+		dict->offsets[i] = cp - data;
+		cp += 2;
+		cp += strlen((const char *)cp) + 1;
+	}
+
+	*offset = curpos;
+	return dict;
+}
-- 
1.8.4.38.g317e65b

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]