Commit Diff


commit - 740c5444001b083fe9c04d809ceec9015bb075fc
commit + a487c1d081edc5ee689dc37477c2740bfbefc127
blob - 65bbcded88384d5d5c7e151f84e6271868044a5d
blob + ebe18b51f48a920944e61349e59e0a689b6ef282
--- include/got_error.h
+++ include/got_error.h
@@ -33,6 +33,7 @@
 #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;
@@ -56,6 +57,7 @@ static const struct got_error {
 	{ 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
@@ -328,89 +328,107 @@ read_packfile_hdr(FILE *f, struct got_packidx_v2_hdr *
 }
 
 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)