summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2007-02-05 05:42:38 (GMT)
committerJunio C Hamano <junkio@cox.net>2007-02-05 22:55:11 (GMT)
commitd66b37bb19ff7a347ba4ccbcdc11b00772518b57 (patch)
treea440601e5e84019b12d4f2b82fe698d93783e361
parent1cfe77333f274c9ba9879c2eb61057a790eb050f (diff)
downloadgit-d66b37bb19ff7a347ba4ccbcdc11b00772518b57.zip
git-d66b37bb19ff7a347ba4ccbcdc11b00772518b57.tar.gz
git-d66b37bb19ff7a347ba4ccbcdc11b00772518b57.tar.bz2
Add pretend_sha1_file() interface.
The new interface allows an application to temporarily hash a small number of objects and pretend that they are available in the object store without actually writing them. Signed-off-by: Junio C Hamano <junkio@cox.net>
-rw-r--r--cache.h1
-rw-r--r--sha1_file.c57
2 files changed, 58 insertions, 0 deletions
diff --git a/cache.h b/cache.h
index 38a9bc0..8714257 100644
--- a/cache.h
+++ b/cache.h
@@ -257,6 +257,7 @@ extern void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, uns
extern void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size);
extern int hash_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *sha1);
extern int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *return_sha1);
+extern int pretend_sha1_file(void *, unsigned long, const char *, unsigned char *);
extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned long size, const char *type);
diff --git a/sha1_file.c b/sha1_file.c
index 1526a28..0d4bf80 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1505,10 +1505,67 @@ static void *read_packed_sha1(const unsigned char *sha1, char *type, unsigned lo
return unpack_entry(e.p, e.offset, type, size);
}
+/*
+ * This is meant to hold a *small* number of objects that you would
+ * want read_sha1_file() to be able to return, but yet you do not want
+ * to write them into the object store (e.g. a browse-only
+ * application).
+ */
+static struct cached_object {
+ unsigned char sha1[20];
+ const char *type;
+ void *buf;
+ unsigned long size;
+} *cached_objects;
+static int cached_object_nr, cached_object_alloc;
+
+static struct cached_object *find_cached_object(const unsigned char *sha1)
+{
+ int i;
+ struct cached_object *co = cached_objects;
+
+ for (i = 0; i < cached_object_nr; i++, co++) {
+ if (!hashcmp(co->sha1, sha1))
+ return co;
+ }
+ return NULL;
+}
+
+int pretend_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *sha1)
+{
+ struct cached_object *co;
+
+ hash_sha1_file(buf, len, type, sha1);
+ if (has_sha1_file(sha1) || find_cached_object(sha1))
+ return 0;
+ if (cached_object_alloc <= cached_object_nr) {
+ cached_object_alloc = alloc_nr(cached_object_alloc);
+ cached_objects = xrealloc(cached_objects,
+ sizeof(*cached_objects) *
+ cached_object_alloc);
+ }
+ co = &cached_objects[cached_object_nr++];
+ co->size = len;
+ co->type = strdup(type);
+ hashcpy(co->sha1, sha1);
+ return 0;
+}
+
void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size)
{
unsigned long mapsize;
void *map, *buf;
+ struct cached_object *co;
+
+ co = find_cached_object(sha1);
+ if (co) {
+ buf = xmalloc(co->size + 1);
+ memcpy(buf, co->buf, co->size);
+ ((char*)buf)[co->size] = 0;
+ strcpy(type, co->type);
+ *size = co->size;
+ return buf;
+ }
buf = read_packed_sha1(sha1, type, size);
if (buf)