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 3, 2009, 18:09 UTC
Message-ID
<1254593401-18801-3-git-send-email-herve@itaapy.com>
In-Reply-To
<1254593401-18801-2-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 a562a19..3cfc932 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.4.4
Previous: Hervé CauwelierNext: Hervé Cauwelier
Message 3 of 8 in “Patches for libgit2”
  1. Hervé CauwelierOct 3, 2009
  2. 1/6 Open the pack file and keep a map on it.Hervé Cauwelier, Oct 3, 2009
  3. 2/6 Read the base offset or name of delta objectsHervé Cauwelier, Oct 3, 2009
  4. 3/6 Allow zlib to read a pack buffer longer than the actual dataHervé Cauwelier, Oct 3, 2009
  5. 4/6 Inflate an object from a pack fileHervé Cauwelier, Oct 3, 2009
  6. 5/6 This assertion is valid for both loose and packed objectsHervé Cauwelier, Oct 3, 2009
  7. 6/6 Read an object from a pack fileHervé Cauwelier, Oct 3, 2009
  8. Shawn O. PearceOct 5, 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.