commit 68482ea3f555f479c9342976a7fbacae381ffc05 from: Stefan Sperling date: Mon Nov 27 04:13:16 2017 UTC implement open/close for blobs; add test which prints one commit - 30b4bb734581ef7586f4c99a6be5675153e3a6df commit + 68482ea3f555f479c9342976a7fbacae381ffc05 blob - d13b60b4636e8d6487f381e4411f9f4167864c19 blob + b96bf6e63fbfc72d14e2b594437e9ce8b5c6ad44 --- include/got_object.h +++ include/got_object.h @@ -14,12 +14,23 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +struct got_zstream_buf { + z_stream z; + char *inbuf; + size_t inlen; + char *outbuf; + size_t outlen; + int flags; +#define GOT_ZSTREAM_F_HAVE_MORE 0x01 +}; + struct got_object_id { u_int8_t sha1[SHA1_DIGEST_LENGTH]; }; struct got_blob_object { - char *dummy; + FILE *f; + struct got_zstream_buf zb; }; struct got_tree_entry { @@ -73,3 +84,8 @@ void got_object_commit_close(struct got_commit_object const struct got_error *got_object_tree_open(struct got_tree_object **, struct got_repository *, struct got_object *); void got_object_tree_close(struct got_tree_object *); +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 *); blob - ba716d03ea4d230704feb345266231ccd3603142 blob + a48d2da75fb713c02727e94d82ccc5cf85f6b8d4 --- lib/object.c +++ lib/object.c @@ -67,16 +67,6 @@ got_object_id_str(struct got_object_id *id, char *buf, return buf; } - -struct got_zstream_buf { - z_stream z; - char *inbuf; - size_t inlen; - char *outbuf; - size_t outlen; - int flags; -#define GOT_ZSTREAM_F_HAVE_MORE 0x01 -}; static void inflate_end(struct got_zstream_buf *zb) @@ -661,4 +651,58 @@ got_object_tree_close(struct got_tree_object *tree) } free(tree); +} + +const struct got_error * +got_object_blob_open(struct got_blob_object **blob, + struct got_repository *repo, struct got_object *obj, size_t blocksize) +{ + const struct got_error *err = NULL; + char *path; + + if (obj->type != GOT_OBJ_TYPE_BLOB) + return got_error(GOT_ERR_OBJ_TYPE); + + err = object_path(&path, &obj->id, repo); + if (err) + return err; + + *blob = calloc(1, sizeof(**blob)); + if (*blob == NULL) { + free(path); + return got_error(GOT_ERR_NO_MEM); + } + + (*blob)->f = fopen(path, "rb"); + if ((*blob)->f == NULL) { + free(*blob); + free(path); + return got_error(GOT_ERR_BAD_PATH); + } + + err = inflate_init(&(*blob)->zb, blocksize); + if (err != NULL) { + fclose((*blob)->f); + free(*blob); + free(path); + return err; + } + + free(path); + return err; } + +void +got_object_blob_close(struct got_blob_object *blob) +{ + inflate_end(&blob->zb); + fclose(blob->f); + free(blob); +} + +const struct got_error * +got_object_blob_read_block(struct got_blob_object *blob, size_t *outlenp) +{ + return inflate_read(&blob->zb, blob->f, outlenp); +} + blob - b299fd1c82f09e8d7eb1da05f0288b581998f571 blob + a754c2376543c040fa032dfb79ea805cf0c912a9 --- lib/refs.c +++ lib/refs.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "got_error.h" #include "got_object.h" blob - 395a24db512cb86c0510ef340e2cc9275c5dd803 blob + e5867e0a5aae93c78d3d5ba2dd7e3ade9b54f54b --- regress/repository/repository_test.c +++ regress/repository/repository_test.c @@ -20,11 +20,13 @@ #include #include #include +#include #include "got_error.h" #include "got_object.h" #include "got_refs.h" #include "got_repository.h" +#include "got_sha1.h" #define RUN_TEST(expr, name) \ if (!(expr)) { printf("test %s failed", (name)); failure = 1; } @@ -184,6 +186,51 @@ repo_read_log(const char *repo_path) return 1; } +static int +repo_read_blob(const char *repo_path) +{ + const char *blob_sha1 = "141f5fdc96126c1f4195558560a3c915e3d9b4c3"; + const struct got_error *err; + struct got_repository *repo; + struct got_object_id id; + struct got_object *obj; + struct got_blob_object *blob; + char hex[SHA1_DIGEST_STRING_LENGTH]; + int i; + size_t len; + + if (!got_parse_sha1_digest(id.sha1, blob_sha1)) + return 0; + + err = got_repo_open(&repo, repo_path); + if (err != NULL || repo == NULL) + return 0; + err = got_object_open(&obj, repo, &id); + if (err != NULL || obj == NULL) + return 0; + if (obj->type != GOT_OBJ_TYPE_BLOB) + return 0; + + err = got_object_blob_open(&blob, repo, obj, 64); + if (err != NULL) + return 0; + + putchar('\n'); + do { + err = got_object_blob_read_block(blob, &len); + if (err) + break; + for (i = 0; i < len; i++) + putchar(blob->zb.outbuf[i]); + } while (len != 0); + putchar('\n'); + + got_object_blob_close(blob); + got_object_close(obj); + got_repo_close(repo); + return (err == NULL); +} + int main(int argc, const char *argv[]) { @@ -200,6 +247,7 @@ main(int argc, const char *argv[]) } RUN_TEST(repo_read_log(repo_path), "read_log"); + RUN_TEST(repo_read_blob(repo_path), "read_blob"); return failure ? 1 : 0; }