diff options
author | Junio C Hamano <junkio@cox.net> | 2007-02-04 21:42:38 -0800 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2007-02-05 14:55:11 -0800 |
commit | d66b37bb19ff7a347ba4ccbcdc11b00772518b57 (patch) | |
tree | a440601e5e84019b12d4f2b82fe698d93783e361 | |
parent | 1cfe77333f274c9ba9879c2eb61057a790eb050f (diff) | |
download | git-d66b37bb19ff7a347ba4ccbcdc11b00772518b57.tar.gz git-d66b37bb19ff7a347ba4ccbcdc11b00772518b57.tar.xz |
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.h | 1 | ||||
-rw-r--r-- | sha1_file.c | 57 |
2 files changed, 58 insertions, 0 deletions
@@ -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 1526a2809..0d4bf80e7 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) |