extern void * map_sha1_file(const unsigned char *sha1, unsigned long *size);
extern void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, unsigned long *size);
extern void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size);
-extern int write_sha1_file(char *buf, unsigned len, unsigned char *return_sha1);
+extern int write_sha1_file(char *buf, unsigned len, const char *type, unsigned char *return_sha1);
extern int check_sha1_signature(unsigned char *sha1, void *buf, unsigned long size, const char *type);
#include <time.h>
#define BLOCKING (1ul << 14)
-#define ORIG_OFFSET (40)
/*
- * Leave space at the beginning to insert the tag
- * once we know how big things are.
- *
* FIXME! Share the code with "write-tree.c"
*/
static void init_buffer(char **bufp, unsigned int *sizep)
{
char *buf = malloc(BLOCKING);
- memset(buf, 0, ORIG_OFFSET);
- *sizep = ORIG_OFFSET;
+ *sizep = 0;
*bufp = buf;
}
memcpy(buf + size, one_line, len);
}
-static int prepend_integer(char *buffer, unsigned val, int i)
-{
- buffer[--i] = '\0';
- do {
- buffer[--i] = '0' + (val % 10);
- val /= 10;
- } while (val);
- return i;
-}
-
-static void finish_buffer(char *tag, char **bufp, unsigned int *sizep)
-{
- int taglen;
- int offset;
- char *buf = *bufp;
- unsigned int size = *sizep;
-
- offset = prepend_integer(buf, size - ORIG_OFFSET, ORIG_OFFSET);
- taglen = strlen(tag);
- offset -= taglen;
- buf += offset;
- size -= offset;
- memcpy(buf, tag, taglen);
-
- *bufp = buf;
- *sizep = size;
-}
-
static void remove_special(char *p)
{
char c;
while (fgets(comment, sizeof(comment), stdin) != NULL)
add_buffer(&buffer, &size, "%s", comment);
- finish_buffer("commit ", &buffer, &size);
-
- write_sha1_file(buffer, size, commit_sha1);
+ write_sha1_file(buffer, size, "commit", commit_sha1);
printf("%s\n", sha1_to_hex(commit_sha1));
return 0;
}
memcpy(buffer, sha1_to_hex(entry->new_sha1), 40);
}
-#define ORIG_OFFSET (40)
-
-static int prepend_integer(char *buffer, unsigned val, int i)
-{
- buffer[--i] = '\0';
- do {
- buffer[--i] = '0' + (val % 10);
- val /= 10;
- } while (val);
- return i;
-}
-
-
static int write_subdirectory(void *buffer, unsigned long size, const char *base, int baselen, unsigned char *result_sha1)
{
- char *new = malloc(size + ORIG_OFFSET);
- unsigned long newlen = ORIG_OFFSET;
+ char *new = malloc(size);
+ unsigned long newlen = 0;
unsigned long used;
- int i;
used = 0;
while (size) {
buffer += len;
}
- i = prepend_integer(new, newlen - ORIG_OFFSET, ORIG_OFFSET);
- i -= 5;
- memcpy(new + i, "tree ", 5);
-
- write_sha1_file(new + i, newlen - i, result_sha1);
+ write_sha1_file(new, newlen, "tree", result_sha1);
free(new);
return used;
}
static void convert_date(void *buffer, unsigned long size, unsigned char *result_sha1)
{
- char *new = malloc(size + ORIG_OFFSET + 100);
- unsigned long newlen = ORIG_OFFSET;
- int i;
+ char *new = malloc(size + 100);
+ unsigned long newlen = 0;
// "tree <sha1>\n"
memcpy(new + newlen, buffer, 46);
memcpy(new + newlen, buffer, size);
newlen += size;
- i = prepend_integer(new, newlen - ORIG_OFFSET, ORIG_OFFSET);
- i -= 7;
- memcpy(new + i, "commit ", 7);
-
- write_sha1_file(new + i, newlen - i, result_sha1);
+ write_sha1_file(new, newlen, "commit", result_sha1);
free(new);
}
struct entry *entry = lookup_entry(sha1);
char type[20];
void *buffer, *data;
- unsigned long size, offset;
+ unsigned long size;
if (entry->converted)
return entry;
if (!data)
die("unable to read object %s", sha1_to_hex(sha1));
- buffer = malloc(size + 100);
- offset = sprintf(buffer, "%s %lu", type, size)+1;
- memcpy(buffer + offset, data, size);
+ buffer = malloc(size);
+ memcpy(buffer, data, size);
if (!strcmp(type, "blob")) {
- write_sha1_file(buffer, size + offset, entry->new_sha1);
+ write_sha1_file(buffer, size, "blob", entry->new_sha1);
} else if (!strcmp(type, "tree"))
- convert_tree(buffer + offset, size, entry->new_sha1);
+ convert_tree(buffer, size, entry->new_sha1);
else if (!strcmp(type, "commit"))
- convert_commit(buffer + offset, size, entry->new_sha1);
+ convert_commit(buffer, size, entry->new_sha1);
else
die("unknown object type '%s' in %s", type, sha1_to_hex(sha1));
entry->converted = 1;
inflateInit(&stream);
ret = inflate(&stream, 0);
- if (ret < Z_OK)
- return NULL;
+ if (ret < Z_OK)
+ return NULL;
if (sscanf(buffer, "%10s %lu", type, size) != 2)
return NULL;
return buffer;
}
-int write_sha1_file(char *buf, unsigned len, unsigned char *returnsha1)
+int write_sha1_file(char *buf, unsigned len, const char *type, unsigned char *returnsha1)
{
int size;
char *compressed;
unsigned char sha1[20];
SHA_CTX c;
char *filename;
- int fd;
+ char hdr[50];
+ int fd, hdrlen;
+
+ /* Generate the header */
+ hdrlen = sprintf(hdr, "%s %d", type, len)+1;
/* Sha1.. */
SHA1_Init(&c);
+ SHA1_Update(&c, hdr, hdrlen);
SHA1_Update(&c, buf, len);
SHA1_Final(sha1, &c);
/* Set it up */
memset(&stream, 0, sizeof(stream));
deflateInit(&stream, Z_BEST_COMPRESSION);
- size = deflateBound(&stream, len);
+ size = deflateBound(&stream, len+hdrlen);
compressed = malloc(size);
/* Compress it */
- stream.next_in = buf;
- stream.avail_in = len;
stream.next_out = compressed;
stream.avail_out = size;
+
+ /* First header.. */
+ stream.next_in = hdr;
+ stream.avail_in = hdrlen;
+ while (deflate(&stream, 0) == Z_OK)
+ /* nothing */
+
+ /* Then the data itself.. */
+ stream.next_in = buf;
+ stream.avail_in = len;
while (deflate(&stream, Z_FINISH) == Z_OK)
/* nothing */;
deflateEnd(&stream);
return ret;
}
-static int prepend_integer(char *buffer, unsigned val, int i)
-{
- buffer[--i] = '\0';
- do {
- buffer[--i] = '0' + (val % 10);
- val /= 10;
- } while (val);
- return i;
-}
-
-#define ORIG_OFFSET (40) /* Enough space to add the header of "tree <size>\0" */
-
static int write_tree(struct cache_entry **cachep, int maxentries, const char *base, int baselen, unsigned char *returnsha1)
{
unsigned char subdir_sha1[20];
unsigned long size, offset;
char *buffer;
- int i, nr;
+ int nr;
/* Guess at some random initial size */
size = 8192;
buffer = malloc(size);
- offset = ORIG_OFFSET;
+ offset = 0;
nr = 0;
do {
nr++;
} while (nr < maxentries);
- i = prepend_integer(buffer, offset - ORIG_OFFSET, ORIG_OFFSET);
- i -= 5;
- memcpy(buffer+i, "tree ", 5);
-
- write_sha1_file(buffer + i, offset - i, returnsha1);
+ write_sha1_file(buffer, offset, "tree", returnsha1);
free(buffer);
return nr;
}