commit - 740c5444001b083fe9c04d809ceec9015bb075fc
commit + a487c1d081edc5ee689dc37477c2740bfbefc127
blob - 65bbcded88384d5d5c7e151f84e6271868044a5d
blob + ebe18b51f48a920944e61349e59e0a689b6ef282
--- include/got_error.h
+++ include/got_error.h
#define GOT_ERR_PACKIDX_CSUM 15
#define GOT_ERR_BAD_PACKFILE 16
#define GOT_ERR_NO_OBJ 17
+#define GOT_ERR_NOT_IMPL 18
static const struct got_error {
int code;
{ GOT_ERR_PACKIDX_CSUM, "pack index file checksum error" },
{ GOT_ERR_BAD_PACKFILE, "bad pack file" },
{ GOT_ERR_NO_OBJ, "object not found" },
+ { GOT_ERR_NOT_IMPL, "feature not implemented" },
};
const struct got_error * got_error(int code);
blob - 1d72c45b4b45fd02412f79ffadcea87f2b55a0e3
blob + dc94a559b6db4076da4c7b2c80a70f615e39aa0b
--- lib/pack.c
+++ lib/pack.c
}
static const struct got_error *
-dump_packed_object(FILE **f, FILE *packfile, off_t offset)
+dump_plain_object(FILE *infile, uint8_t type, uint64_t size, FILE *outfile)
{
- const struct got_error *err = NULL;
- const char *template = "/tmp/got.XXXXXXXXXX";
- uint64_t size = 0;
- uint8_t type = 0;
- uint8_t sizeN;
- int i;
- size_t n;
- const char *type_tag;
+ const char *type_tag = got_object_get_type_tag(type);
+ size_t n;
- *f = got_opentemp();
- if (*f == NULL) {
- err = got_error(GOT_ERR_FILE_OPEN);
- goto done;
- }
+ if (type_tag == NULL)
+ return got_error(GOT_ERR_OBJ_TYPE);
- if (fseeko(packfile, offset, SEEK_SET) != 0) {
- err = got_error_from_errno();
- goto done;
+ 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;
}
- i = 0;
+ return NULL;
+}
+
+static const struct got_error *
+decode_type_and_size(uint8_t *type, uint64_t *size, FILE *packfile)
+{
+ uint8_t t = 0;
+ uint64_t s = 0;
+ uint8_t sizeN;
+ size_t n;
+ int i = 0;
+
do {
/* We do not support size values which don't fit in 64 bit. */
- if (i > 9) {
- err = got_error(GOT_ERR_NO_SPACE);
- goto done;
- }
+ if (i > 9)
+ return got_error(GOT_ERR_NO_SPACE);
n = fread(&sizeN, sizeof(sizeN), 1, packfile);
- if (n != 1) {
- err = got_ferror(packfile, GOT_ERR_BAD_PACKIDX);
- goto done;
- }
+ if (n != 1)
+ return got_ferror(packfile, GOT_ERR_BAD_PACKIDX);
if (i == 0) {
- type = (sizeN & GOT_PACK_OBJ_SIZE0_TYPE_MASK) >>
+ t = (sizeN & GOT_PACK_OBJ_SIZE0_TYPE_MASK) >>
GOT_PACK_OBJ_SIZE0_TYPE_MASK_SHIFT;
- size = (sizeN & GOT_PACK_OBJ_SIZE0_VAL_MASK);
+ s = (sizeN & GOT_PACK_OBJ_SIZE0_VAL_MASK);
} else {
size_t shift = 4 + 7 * (i - 1);
- size |= ((sizeN & GOT_PACK_OBJ_SIZE_VAL_MASK) << shift);
+ s |= ((sizeN & GOT_PACK_OBJ_SIZE_VAL_MASK) << shift);
}
i++;
} while (sizeN & GOT_PACK_OBJ_SIZE_MORE);
- if (type == GOT_OBJ_TYPE_OFFSET_DELTA)
- printf("object type OFFSET_DELTA not yet implemented\n");
- else if (type == GOT_OBJ_TYPE_REF_DELTA)
- printf("object type REF_DELTA not yet implemented\n");
- else if (type == GOT_OBJ_TYPE_TAG)
- printf("object type TAG not yet implemented\n");
+ *type = t;
+ *size = s;
+ return NULL;
+}
- type_tag = got_object_get_type_tag(type);
- if (type_tag == NULL) {
- err = got_error(GOT_ERR_BAD_OBJ_HDR);
+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;
}
- fprintf(*f, "%s %llu", type_tag, size);
- fputc('\0', *f);
+ if (fseeko(packfile, offset, SEEK_SET) != 0) {
+ err = got_error_from_errno();
+ goto done;
+ }
- while (size > 0) {
- uint8_t data[2048];
- size_t len = MIN(size, sizeof(data));
+ err = decode_type_and_size(&type, &size, packfile);
+ if (err)
+ goto done;
- n = fread(data, len, 1, packfile);
- if (n != 1) {
- err = got_ferror(packfile, GOT_ERR_BAD_PACKIDX);
- goto done;
- }
-
- n = fwrite(data, len, 1, *f);
- if (n != 1) {
- err = got_ferror(*f, GOT_ERR_BAD_PACKIDX);
- goto done;
- }
-
- size -= len;
+ 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;
}
- printf("object type is %d\n", type);
rewind(*f);
done:
if (err && *f)