commit - a92b0c17291b08d61cbe30b1e639a6331606218b
commit + 6c00b54532f90be3b76dd1aed025376a35dc35de
blob - 9e3f32b04c48fb04b77e6f8312deb951ae55ea31
blob + 204947b421455ff730a46fe0ff59b72331ec8a6a
--- include/got_object.h
+++ include/got_object.h
#define GOT_OBJ_TYPE_OFFSET_DELTA 6
#define GOT_OBJ_TYPE_REF_DELTA 7
+ int flags;
+#define GOT_OBJ_FLAG_PACKED 0x01
+
size_t hdrlen;
size_t size;
struct got_object_id id;
+
+ char *path_packfile;
+ off_t pack_offset;
};
struct got_repository;
blob - a0ff6db1d758648a099b4c092d5950ce875c5333
blob + f3581b6726ebe6258178022ac2703b58f32165bb
--- lib/object.c
+++ lib/object.c
n = fread(zb->inbuf, 1, zb->inlen, f);
if (n == 0) {
if (ferror(f))
- return got_error(GOT_ERR_IO);
+ return got_ferror(f, GOT_ERR_IO);
*outlenp = 0;
return NULL;
}
return err;
}
-static const struct got_error *
-open_object(FILE **f, struct got_object_id *id, struct got_repository *repo)
+const struct got_error *
+open_object(FILE **f, struct got_object *obj, struct got_repository *repo)
{
const struct got_error *err = NULL;
char *path;
- err = object_path(&path, id, repo);
+ if (obj->flags & GOT_OBJ_FLAG_PACKED) {
+ return got_error(GOT_ERR_NOT_IMPL);
+ }
+
+ err = object_path(&path, &obj->id, repo);
if (err)
return err;
-
*f = fopen(path, "rb");
if (*f == NULL) {
- if (errno != ENOENT) {
- err = got_error_from_errno();
- goto done;
- }
- err = got_packfile_extract_object(f, id, repo);
- if (err)
- goto done;
- if (*f == NULL) {
- err = got_error(GOT_ERR_NO_OBJ);
- goto done;
- }
+ err = got_error_from_errno();
+ goto done;
}
done:
free(path);
- if (err && *f != NULL)
- fclose(*f);
return err;
}
got_object_open(struct got_object **obj, struct got_repository *repo,
struct got_object_id *id)
{
- const struct got_error *err;
+ const struct got_error *err = NULL;
+ char *path;
FILE *f;
- err = open_object(&f, id, repo);
+ err = object_path(&path, id, repo);
if (err)
return err;
- err = read_object_header(obj, repo, f);
- if (err == NULL)
+ f = fopen(path, "rb");
+ if (f == NULL) {
+ if (errno != ENOENT) {
+ err = got_error_from_errno();
+ goto done;
+ }
+ err = got_packfile_open_object(obj, id, repo);
+ if (err)
+ goto done;
+ if (*obj == NULL)
+ err = got_error(GOT_ERR_NO_OBJ);
+ } else {
+ err = read_object_header(obj, repo, f);
+ if (err)
+ goto done;
memcpy((*obj)->id.sha1, id->sha1, SHA1_DIGEST_LENGTH);
- else
+ }
+done:
+ free(path);
+ if (err && f)
fclose(f);
return err;
+
}
void
got_object_close(struct got_object *obj)
{
+ free(obj->path_packfile);
free(obj);
}
if (obj->type != GOT_OBJ_TYPE_COMMIT)
return got_error(GOT_ERR_OBJ_TYPE);
- err = open_object(&f, &obj->id, repo);
+ err = open_object(&f, obj, repo);
if (err)
return err;
if (obj->type != GOT_OBJ_TYPE_TREE)
return got_error(GOT_ERR_OBJ_TYPE);
- err = open_object(&f, &obj->id, repo);
+ err = open_object(&f, obj, repo);
if (err)
return err;
if (*blob == NULL)
return got_error(GOT_ERR_NO_MEM);
- err = open_object(&((*blob)->f), &obj->id, repo);
+ err = open_object(&((*blob)->f), obj, repo);
if (err) {
free(*blob);
return err;
blob - dc94a559b6db4076da4c7b2c80a70f615e39aa0b
blob + 7e7325a8f390d9822562634b04bd0eb7fc9da742
--- lib/pack.c
+++ lib/pack.c
i = betoh32(packidx->fanout_table[id0 - 1]);
while (i < totobj) {
- struct got_object_id *oid = &packidx->sorted_ids[i++];
+ struct got_object_id *oid = &packidx->sorted_ids[i];
uint32_t offset;
int cmp = got_object_id_cmp(id, oid);
- if (cmp < 0)
- continue;
- if (cmp > 0)
+ if (cmp == 0)
+ return i;
+ else if (cmp > 0)
break;
-
- return i;
+ i++;
}
return -1;
err = got_error(GOT_ERR_BAD_PACKFILE);
return err;
-}
-
-static const struct got_error *
-dump_plain_object(FILE *infile, uint8_t type, uint64_t size, FILE *outfile)
-{
- const char *type_tag = got_object_get_type_tag(type);
- size_t n;
-
- if (type_tag == NULL)
- return got_error(GOT_ERR_OBJ_TYPE);
-
- fprintf(outfile, "%s %llu", type_tag, size);
- fputc('\0', outfile);
-
- while (size > 0) {
- uint8_t data[2048];
- size_t len = MIN(size, sizeof(data));
-
- n = fread(data, len, 1, infile);
- if (n != 1)
- return got_ferror(infile, GOT_ERR_BAD_PACKIDX);
-
- n = fwrite(data, len, 1, outfile);
- if (n != 1)
- return got_ferror(outfile, GOT_ERR_BAD_PACKIDX);
-
- size -= len;
- }
-
- return NULL;
}
static const struct got_error *
*type = t;
*size = s;
return NULL;
-}
-
-static const struct got_error *
-dump_packed_object(FILE **f, FILE *packfile, off_t offset)
-{
- const struct got_error *err = NULL;
- const char *template = "/tmp/got.XXXXXXXXXX";
- uint8_t type;
- uint64_t size;
- FILE *outfile = NULL;
-
- *f = got_opentemp();
- if (*f == NULL) {
- err = got_error(GOT_ERR_FILE_OPEN);
- goto done;
- }
-
- if (fseeko(packfile, offset, SEEK_SET) != 0) {
- err = got_error_from_errno();
- goto done;
- }
-
- err = decode_type_and_size(&type, &size, packfile);
- if (err)
- goto done;
-
- switch (type) {
- case GOT_OBJ_TYPE_COMMIT:
- case GOT_OBJ_TYPE_TREE:
- case GOT_OBJ_TYPE_BLOB:
- err = dump_plain_object(packfile, type, size, *f);
- break;
- case GOT_OBJ_TYPE_REF_DELTA:
- case GOT_OBJ_TYPE_TAG:
- case GOT_OBJ_TYPE_OFFSET_DELTA:
- default:
- err = got_error(GOT_ERR_NOT_IMPL);
- goto done;
- }
-
- rewind(*f);
-done:
- if (err && *f)
- fclose(*f);
- return err;
}
static const struct got_error *
-extract_object(FILE **f, const char *path_packdir,
- struct got_packidx_v2_hdr *packidx, struct got_object_id *id)
+open_packed_object(struct got_object **obj, struct got_repository *repo,
+ const char *path_packdir, struct got_packidx_v2_hdr *packidx,
+ struct got_object_id *id)
{
const struct got_error *err = NULL;
int idx = get_object_idx(packidx, id);
off_t offset;
- char *path_packfile;
- FILE *packfile;
char hex[SHA1_DIGEST_STRING_LENGTH];
char *sha1str;
+ char *path_packfile;
+ FILE *packfile;
+ uint8_t type;
+ uint64_t size;
- *f = NULL;
+ *obj = NULL;
if (idx == -1) /* object not found in pack index */
return NULL;
if (err)
goto done;
- printf("Dumping object at offset %llu\n", offset);
- err = dump_packed_object(f, packfile, offset);
+ if (fseeko(packfile, offset, SEEK_SET) != 0) {
+ err = got_error_from_errno();
+ goto done;
+ }
+
+ err = decode_type_and_size(&type, &size, packfile);
if (err)
goto done;
+ *obj = calloc(1, sizeof(**obj));
+ if (*obj == NULL) {
+ err = got_error(GOT_ERR_NO_MEM);
+ goto done;
+ }
+
+ switch (type) {
+ case GOT_OBJ_TYPE_COMMIT:
+ case GOT_OBJ_TYPE_TREE:
+ case GOT_OBJ_TYPE_BLOB:
+ (*obj)->path_packfile = strdup(path_packfile);
+ if ((*obj)->path_packfile == NULL) {
+ err = got_error(GOT_ERR_NO_MEM);
+ goto done;
+ }
+ (*obj)->type = type;
+ (*obj)->flags = GOT_OBJ_FLAG_PACKED;
+ (*obj)->hdrlen = 0;
+ (*obj)->size = size;
+ memcpy(&(*obj)->id, id, sizeof((*obj)->id));
+ (*obj)->pack_offset = offset;
+ break;
+ case GOT_OBJ_TYPE_REF_DELTA:
+ case GOT_OBJ_TYPE_TAG:
+ case GOT_OBJ_TYPE_OFFSET_DELTA:
+ default:
+ err = got_error(GOT_ERR_NOT_IMPL);
+ goto done;
+ }
done:
free(path_packfile);
+ if (err)
+ free(*obj);
if (packfile && fclose(packfile) == -1 && err == 0)
err = got_error_from_errno();
return err;
}
const struct got_error *
-got_packfile_extract_object(FILE **f, struct got_object_id *id,
+got_packfile_open_object(struct got_object **obj, struct got_object_id *id,
struct got_repository *repo)
{
const struct got_error *err = NULL;
if (err)
goto done;
- err = extract_object(f, path_packdir, packidx, id);
+ err = open_packed_object(obj, repo, path_packdir, packidx, id);
if (err)
goto done;
- if (*f != NULL)
+ if (*obj != NULL)
break;
}
blob - 9e034eb2f7ab046e1448b158af3478bdf73aee1b
blob + e26be48fe9e5fa02953cf19e02932e77d46a40d5
--- lib/pack.h
+++ lib/pack.h
const char *);
void got_packidx_close(struct got_packidx_v2_hdr *);
-const struct got_error *got_packfile_extract_object(FILE **,
+const struct got_error *got_packfile_open_object(struct got_object **,
struct got_object_id *, struct got_repository *);