git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 2/6] Read the base offset or name of delta objects

From
HCHervé Cauwelier <herve@itaapy.com>
Date
Oct 14, 2009, 10:37 UTC
Message-ID
<1255516669-26745-2-git-send-email-herve@itaapy.com>
In-Reply-To
<1255516669-26745-1-git-send-email-herve@itaapy.com>
Signed-off-by: Hervé Cauwelier <herve@itaapy.com>
---
 src/cc-compat.h |    3 +++
 src/odb.c       |   28 ++++++++++++++++++++++++++--
 2 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/src/cc-compat.h b/src/cc-compat.h
index 8997caa..8dd6774 100644
--- a/src/cc-compat.h
+++ b/src/cc-compat.h
@@ -30,6 +30,9 @@
 # define GIT_TYPEOF(x)
 #endif
 
+#define bitsizeof(x)  (CHAR_BIT * sizeof(x))
+#define MSB(x, bits) ((x) & GIT_TYPEOF(x)(~0ULL << (bitsizeof(x) - (bits))))
+
 /*
  * Does our compiler/platform support the C99 <inttypes.h> and
  * <stdint.h> header files. (C99 requires that <inttypes.h>
diff --git a/src/odb.c b/src/odb.c
index 2319998..2b4b016 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -97,8 +97,10 @@ struct git_odb {
 };
 
 typedef struct {  /* object header data */
-	git_otype type;  /* object type */
-	size_t    size;  /* object size */
+	git_otype type;         /* object type */
+	size_t    size;         /* object size */
+	off_t     base_offset;  /* delta base offset (GIT_OBJ_OFS_DELTA) */
+	git_oid   base_name;    /* delta base name (GIT_OBJ_REF_DELTA) */
 } obj_hdr;
 
 static struct {
@@ -238,6 +240,7 @@ static size_t get_binary_object_header(obj_hdr *hdr, gitfo_buf *obj)
 	unsigned char c;
 	unsigned char *data = obj->data;
 	size_t shift, size, used = 0;
+	off_t base_offset;
 
 	if (obj->len == 0)
 		return 0;
@@ -258,6 +261,27 @@ static size_t get_binary_object_header(obj_hdr *hdr, gitfo_buf *obj)
 	}
 	hdr->size = size;
 
+	hdr->base_offset = 0;
+	hdr->base_name.id[0] = '\0';
+
+	if (hdr->type == GIT_OBJ_OFS_DELTA) {
+		c = data[used++];
+		base_offset = c & 127;
+		while (c & 128) {
+			base_offset++;
+			if (!base_offset || MSB(base_offset, 7))
+				return 0;  /* overflow */
+			c = data[used++];
+			base_offset = (base_offset << 7) + (c & 127);
+		}
+		assert(base_offset > 0);
+		hdr->base_offset = base_offset;
+	}
+	else if (hdr->type == GIT_OBJ_REF_DELTA) {
+		git_oid_mkraw(&hdr->base_name, data + used);
+		used += 20;
+	}
+
 	return used;
 }
 
-- 
1.6.5
Previous: Hervé CauwelierNext: Hervé Cauwelier
Message 2 of 9 in “Open the pack file and keep a map on it.”
  1. 1/6 Open the pack file and keep a map on it.Hervé Cauwelier, Oct 14, 2009
  2. 2/6 Read the base offset or name of delta objectsHervé Cauwelier, Oct 14, 2009
  3. 3/6 Allow zlib to read a pack buffer longer than the actual dataHervé Cauwelier, Oct 14, 2009
  4. 4/6 Inflate an object from a pack fileHervé Cauwelier, Oct 14, 2009
  5. 5/6 This assertion is valid for both loose and packed objectsHervé Cauwelier, Oct 14, 2009
  6. 6/6 Read an object from a pack fileHervé Cauwelier, Oct 14, 2009
  7. Sverre RabbelierOct 14, 2009
  8. Hervé CauwelierOct 14, 2009
  9. Sverre RabbelierOct 14, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.