commit - 126ee0608bd8017ef807797e24616f07bfe7936c
commit + eb651edf82ab7e2ac9f92490d1444c3341843ac7
blob - 59e948f3f74afcf024e1cab33edf5d0b56c585e7
blob + 339b6c1b3cd86d892dc0c1e5df004c0c974d64fb
--- include/got_object.h
+++ include/got_object.h
FILE *f;
struct got_zstream_buf zb;
size_t hdrlen;
+ size_t blocksize;
+ uint8_t *read_buf;
+ int flags;
+#define GOT_BLOB_F_COMPRESSED 0x01
struct got_object_id id;
};
const struct got_error *got_object_blob_open(struct got_blob_object **,
struct got_repository *, struct got_object *, size_t);
void got_object_blob_close(struct got_blob_object *);
-const struct got_error *got_object_blob_read_block(struct got_blob_object *,
- size_t *);
+const struct got_error *got_object_blob_read_block(size_t *,
+ struct got_blob_object *);
blob - cbf2d2f60d7587c6052b0de1eadc1f894429b51d
blob + 0cb5c034868325c64141658c3b8fc4ea9a7e5e2b
--- lib/diff.c
+++ lib/diff.c
idstr1 = got_object_id_str(&blob1->id, hex1, sizeof(hex1));
hdrlen = blob1->hdrlen;
do {
- err = got_object_blob_read_block(blob1, &len);
+ err = got_object_blob_read_block(&len, blob1);
if (err)
goto done;
/* Skip blob object header first time around. */
- fwrite(blob1->zb.outbuf + hdrlen, len - hdrlen, 1, f1);
+ fwrite(blob1->read_buf + hdrlen, len - hdrlen, 1, f1);
hdrlen = 0;
} while (len != 0);
} else
idstr2 = got_object_id_str(&blob2->id, hex2, sizeof(hex2));
hdrlen = blob2->hdrlen;
do {
- err = got_object_blob_read_block(blob2, &len);
+ err = got_object_blob_read_block(&len, blob2);
if (err)
goto done;
/* Skip blob object header first time around. */
- fwrite(blob2->zb.outbuf + hdrlen, len - hdrlen, 1, f2);
+ fwrite(blob2->read_buf + hdrlen, len - hdrlen, 1, f2);
hdrlen = 0;
} while (len != 0);
} else
blob - 17771727f543eca5683a8c29ee19cc0995a32321
blob + 273788d7f3ccc4a3162819094255583f4e60e88b
--- lib/object.c
+++ lib/object.c
}
static const struct got_error *
-fopen_object(FILE **f, struct got_object *obj, struct got_repository *repo)
+open_loose_object(FILE **f, struct got_object *obj, struct got_repository *repo)
{
const struct got_error *err = NULL;
char *path;
-
- if (obj->flags & GOT_OBJ_FLAG_PACKED)
- return got_packfile_extract_object(f, obj, repo);
err = object_path(&path, &obj->id, repo);
if (err)
SIMPLEQ_INSERT_TAIL(&(*commit)->parent_ids, pid, entry);
(*commit)->nparents++;
+ remain -= SHA1_DIGEST_STRING_LENGTH;
s += SHA1_DIGEST_STRING_LENGTH;
}
goto done;
}
s += strlen((*commit)->author) + 1;
+ remain -= strlen((*commit)->author) + 1;
}
tlen = strlen(GOT_COMMIT_TAG_COMMITTER);
goto done;
}
s += strlen((*commit)->committer) + 1;
+ remain -= strlen((*commit)->committer) + 1;
}
- (*commit)->logmsg = strdup(s);
+ (*commit)->logmsg = strndup(s, remain);
+ if ((*commit)->logmsg == NULL) {
+ err = got_error(GOT_ERR_NO_MEM);
+ goto done;
+ }
done:
if (err)
got_object_commit_close(*commit);
}
static const struct got_error *
+read_to_mem(uint8_t **outbuf, size_t *outlen, FILE *f)
+{
+ const struct got_error *err = NULL;
+ static const size_t blocksize = 512;
+ size_t n, total, remain;
+ uint8_t *buf;
+
+ *outbuf = NULL;
+ *outlen = 0;
+
+ buf = calloc(1, blocksize);
+ if (buf == NULL)
+ return got_error(GOT_ERR_NO_MEM);
+
+ remain = blocksize;
+ total = 0;
+ while (1) {
+ if (remain == 0) {
+ uint8_t *newbuf;
+ newbuf = reallocarray(buf, 1, total + blocksize);
+ if (newbuf == NULL) {
+ err = got_error(GOT_ERR_NO_MEM);
+ goto done;
+ }
+ buf = newbuf;
+ remain += blocksize;
+ }
+ n = fread(buf, 1, remain, f);
+ if (n == 0) {
+ if (ferror(f)) {
+ err = got_ferror(f, GOT_ERR_IO);
+ goto done;
+ }
+ break; /* EOF */
+ }
+ remain -= n;
+ total += n;
+ };
+
+done:
+ if (err == NULL) {
+ *outbuf = buf;
+ *outlen = total;
+ } else
+ free(buf);
+ return err;
+}
+
+static const struct got_error *
read_commit_object(struct got_commit_object **commit,
struct got_repository *repo, struct got_object *obj, FILE *f)
{
const struct got_error *err = NULL;
- struct got_zstream_buf zb;
size_t len;
- char *p;
+ uint8_t *p;
int i, ret;
- err = got_inflate_init(&zb, 8192);
+ if (obj->flags & GOT_OBJ_FLAG_PACKED)
+ err = read_to_mem(&p, &len, f);
+ else
+ err = got_inflate_to_mem(&p, &len, f);
if (err)
return err;
- err = got_inflate_read(&zb, f, &len);
- if (err)
- return err;
-
if (len < obj->hdrlen + obj->size) {
err = got_error(GOT_ERR_BAD_OBJ_DATA);
goto done;
/* Skip object header. */
len -= obj->hdrlen;
- err = parse_commit_object(commit, zb.outbuf + obj->hdrlen, len);
+ err = parse_commit_object(commit, p + obj->hdrlen, len);
+ free(p);
done:
- got_inflate_end(&zb);
return err;
}
if (obj->type != GOT_OBJ_TYPE_COMMIT)
return got_error(GOT_ERR_OBJ_TYPE);
- err = fopen_object(&f, obj, repo);
+ if (obj->flags & GOT_OBJ_FLAG_PACKED)
+ err = got_packfile_extract_object(&f, obj, repo);
+ else
+ err = open_loose_object(&f, obj, repo);
if (err)
return err;
struct got_repository *repo, struct got_object *obj, FILE *f)
{
const struct got_error *err = NULL;
- struct got_zstream_buf zb;
size_t len;
- char *p;
+ uint8_t *p;
int i, ret;
- err = got_inflate_init(&zb, 8192);
+ if (obj->flags & GOT_OBJ_FLAG_PACKED)
+ err = read_to_mem(&p, &len, f);
+ else
+ err = got_inflate_to_mem(&p, &len, f);
if (err)
return err;
- err = got_inflate_read(&zb, f, &len);
- if (err)
- return err;
-
if (len < obj->hdrlen + obj->size) {
err = got_error(GOT_ERR_BAD_OBJ_DATA);
goto done;
/* Skip object header. */
len -= obj->hdrlen;
- err = parse_tree_object(tree, repo, zb.outbuf + obj->hdrlen, len);
+ err = parse_tree_object(tree, repo, p + obj->hdrlen, len);
+ free(p);
done:
- got_inflate_end(&zb);
return err;
}
if (obj->type != GOT_OBJ_TYPE_TREE)
return got_error(GOT_ERR_OBJ_TYPE);
- err = fopen_object(&f, obj, repo);
+ if (obj->flags & GOT_OBJ_FLAG_PACKED)
+ err = got_packfile_extract_object(&f, obj, repo);
+ else
+ err = open_loose_object(&f, obj, repo);
if (err)
return err;
if (*blob == NULL)
return got_error(GOT_ERR_NO_MEM);
- err = fopen_object(&((*blob)->f), obj, repo);
- if (err) {
- free(*blob);
- return err;
- }
+ if (obj->flags & GOT_OBJ_FLAG_PACKED) {
+ (*blob)->read_buf = calloc(1, blocksize);
+ if ((*blob)->read_buf == NULL)
+ return got_error(GOT_ERR_NO_MEM);
+ err = got_packfile_extract_object(&((*blob)->f), obj, repo);
+ if (err)
+ return err;
+ } else {
+ err = open_loose_object(&((*blob)->f), obj, repo);
+ if (err) {
+ free(*blob);
+ return err;
+ }
- err = got_inflate_init(&(*blob)->zb, blocksize);
- if (err != NULL) {
- fclose((*blob)->f);
- free(*blob);
- return err;
+ err = got_inflate_init(&(*blob)->zb, blocksize);
+ if (err != NULL) {
+ fclose((*blob)->f);
+ free(*blob);
+ return err;
+ }
+
+ (*blob)->read_buf = (*blob)->zb.outbuf;
+ (*blob)->flags |= GOT_BLOB_F_COMPRESSED;
}
(*blob)->hdrlen = obj->hdrlen;
+ (*blob)->blocksize = blocksize;
memcpy(&(*blob)->id.sha1, obj->id.sha1, SHA1_DIGEST_LENGTH);
return err;
void
got_object_blob_close(struct got_blob_object *blob)
{
- got_inflate_end(&blob->zb);
+ if (blob->flags & GOT_BLOB_F_COMPRESSED)
+ got_inflate_end(&blob->zb);
+ else
+ free(blob->read_buf);
fclose(blob->f);
free(blob);
}
const struct got_error *
-got_object_blob_read_block(struct got_blob_object *blob, size_t *outlenp)
+got_object_blob_read_block(size_t *outlenp, struct got_blob_object *blob)
{
- return got_inflate_read(&blob->zb, blob->f, outlenp);
+ size_t n;
+
+ if (blob->flags & GOT_BLOB_F_COMPRESSED)
+ return got_inflate_read(&blob->zb, blob->f, outlenp);
+
+ n = fread(blob->read_buf, 1, blob->blocksize, blob->f);
+ if (n == 0 && ferror(blob->f))
+ return got_ferror(blob->f, GOT_ERR_IO);
+ *outlenp = n;
+ return NULL;
}
blob - 986eedb02f9ed69e552be11d888ac3dd8e4730d1
blob + 7028965f2cdb7f4256b2950f284585ebe185e6cd
--- regress/repository/repository_test.c
+++ regress/repository/repository_test.c
test_printf("\n");
do {
- err = got_object_blob_read_block(blob, &len);
+ err = got_object_blob_read_block(&len, blob);
if (err)
break;
for (i = 0; i < len; i++)
- test_printf("%c", blob->zb.outbuf[i]);
+ test_printf("%c", blob->read_buf[i]);
} while (len != 0);
test_printf("\n");